ActivityManagerService.java revision 86677c9a511f4478bf94418208e600b1f40db733
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.os.storage.IMountService;
52import android.os.storage.StorageManager;
53import android.service.voice.IVoiceInteractionSession;
54import android.util.ArrayMap;
55import android.util.ArraySet;
56import android.util.SparseIntArray;
57
58import com.android.internal.R;
59import com.android.internal.annotations.GuardedBy;
60import com.android.internal.app.IAppOpsService;
61import com.android.internal.app.IVoiceInteractor;
62import com.android.internal.app.ProcessMap;
63import com.android.internal.app.ProcessStats;
64import com.android.internal.content.PackageMonitor;
65import com.android.internal.os.BackgroundThread;
66import com.android.internal.os.BatteryStatsImpl;
67import com.android.internal.os.ProcessCpuTracker;
68import com.android.internal.os.TransferPipe;
69import com.android.internal.os.Zygote;
70import com.android.internal.util.FastPrintWriter;
71import com.android.internal.util.FastXmlSerializer;
72import com.android.internal.util.MemInfoReader;
73import com.android.internal.util.Preconditions;
74import com.android.server.AppOpsService;
75import com.android.server.AttributeCache;
76import com.android.server.IntentResolver;
77import com.android.server.LocalServices;
78import com.android.server.ServiceThread;
79import com.android.server.SystemService;
80import com.android.server.SystemServiceManager;
81import com.android.server.Watchdog;
82import com.android.server.am.ActivityStack.ActivityState;
83import com.android.server.firewall.IntentFirewall;
84import com.android.server.pm.Installer;
85import com.android.server.pm.UserManagerService;
86import com.android.server.statusbar.StatusBarManagerInternal;
87import com.android.server.wm.AppTransition;
88import com.android.server.wm.WindowManagerService;
89import com.google.android.collect.Lists;
90import com.google.android.collect.Maps;
91
92import libcore.io.IoUtils;
93
94import org.xmlpull.v1.XmlPullParser;
95import org.xmlpull.v1.XmlPullParserException;
96import org.xmlpull.v1.XmlSerializer;
97
98import android.app.Activity;
99import android.app.ActivityManager;
100import android.app.ActivityManager.RunningTaskInfo;
101import android.app.ActivityManager.StackInfo;
102import android.app.ActivityManagerInternal;
103import android.app.ActivityManagerNative;
104import android.app.ActivityOptions;
105import android.app.ActivityThread;
106import android.app.AlertDialog;
107import android.app.AppGlobals;
108import android.app.ApplicationErrorReport;
109import android.app.Dialog;
110import android.app.IActivityController;
111import android.app.IApplicationThread;
112import android.app.IInstrumentationWatcher;
113import android.app.INotificationManager;
114import android.app.IProcessObserver;
115import android.app.IServiceConnection;
116import android.app.IStopUserCallback;
117import android.app.IUiAutomationConnection;
118import android.app.IUserSwitchObserver;
119import android.app.Instrumentation;
120import android.app.Notification;
121import android.app.NotificationManager;
122import android.app.PendingIntent;
123import android.app.backup.IBackupManager;
124import android.content.ActivityNotFoundException;
125import android.content.BroadcastReceiver;
126import android.content.ClipData;
127import android.content.ComponentCallbacks2;
128import android.content.ComponentName;
129import android.content.ContentProvider;
130import android.content.ContentResolver;
131import android.content.Context;
132import android.content.DialogInterface;
133import android.content.IContentProvider;
134import android.content.IIntentReceiver;
135import android.content.IIntentSender;
136import android.content.Intent;
137import android.content.IntentFilter;
138import android.content.IntentSender;
139import android.content.pm.ActivityInfo;
140import android.content.pm.ApplicationInfo;
141import android.content.pm.ConfigurationInfo;
142import android.content.pm.IPackageDataObserver;
143import android.content.pm.IPackageManager;
144import android.content.pm.InstrumentationInfo;
145import android.content.pm.PackageInfo;
146import android.content.pm.PackageManager;
147import android.content.pm.ParceledListSlice;
148import android.content.pm.UserInfo;
149import android.content.pm.PackageManager.NameNotFoundException;
150import android.content.pm.PathPermission;
151import android.content.pm.ProviderInfo;
152import android.content.pm.ResolveInfo;
153import android.content.pm.ServiceInfo;
154import android.content.res.CompatibilityInfo;
155import android.content.res.Configuration;
156import android.net.Proxy;
157import android.net.ProxyInfo;
158import android.net.Uri;
159import android.os.Binder;
160import android.os.Build;
161import android.os.Bundle;
162import android.os.Debug;
163import android.os.DropBoxManager;
164import android.os.Environment;
165import android.os.FactoryTest;
166import android.os.FileObserver;
167import android.os.FileUtils;
168import android.os.Handler;
169import android.os.IBinder;
170import android.os.IPermissionController;
171import android.os.IRemoteCallback;
172import android.os.IUserManager;
173import android.os.Looper;
174import android.os.Message;
175import android.os.Parcel;
176import android.os.ParcelFileDescriptor;
177import android.os.Process;
178import android.os.RemoteCallbackList;
179import android.os.RemoteException;
180import android.os.SELinux;
181import android.os.ServiceManager;
182import android.os.StrictMode;
183import android.os.SystemClock;
184import android.os.SystemProperties;
185import android.os.UpdateLock;
186import android.os.UserHandle;
187import android.os.UserManager;
188import android.provider.Settings;
189import android.text.format.DateUtils;
190import android.text.format.Time;
191import android.util.AtomicFile;
192import android.util.EventLog;
193import android.util.Log;
194import android.util.Pair;
195import android.util.PrintWriterPrinter;
196import android.util.Slog;
197import android.util.SparseArray;
198import android.util.TimeUtils;
199import android.util.Xml;
200import android.view.Gravity;
201import android.view.LayoutInflater;
202import android.view.View;
203import android.view.WindowManager;
204
205import dalvik.system.VMRuntime;
206
207import java.io.BufferedInputStream;
208import java.io.BufferedOutputStream;
209import java.io.DataInputStream;
210import java.io.DataOutputStream;
211import java.io.File;
212import java.io.FileDescriptor;
213import java.io.FileInputStream;
214import java.io.FileNotFoundException;
215import java.io.FileOutputStream;
216import java.io.IOException;
217import java.io.InputStreamReader;
218import java.io.PrintWriter;
219import java.io.StringWriter;
220import java.lang.ref.WeakReference;
221import java.util.ArrayList;
222import java.util.Arrays;
223import java.util.Collections;
224import java.util.Comparator;
225import java.util.HashMap;
226import java.util.HashSet;
227import java.util.Iterator;
228import java.util.List;
229import java.util.Locale;
230import java.util.Map;
231import java.util.Set;
232import java.util.concurrent.atomic.AtomicBoolean;
233import java.util.concurrent.atomic.AtomicLong;
234
235public final class ActivityManagerService extends ActivityManagerNative
236        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
237
238    private static final String USER_DATA_DIR = "/data/user/";
239    // File that stores last updated system version and called preboot receivers
240    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
241
242    static final String TAG = "ActivityManager";
243    static final String TAG_MU = "ActivityManagerServiceMU";
244    static final boolean DEBUG = false;
245    static final boolean localLOGV = DEBUG;
246    static final boolean DEBUG_BACKUP = localLOGV || false;
247    static final boolean DEBUG_BROADCAST = localLOGV || false;
248    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
249    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
250    static final boolean DEBUG_CLEANUP = localLOGV || false;
251    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
252    static final boolean DEBUG_FOCUS = false;
253    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
254    static final boolean DEBUG_MU = localLOGV || false;
255    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
256    static final boolean DEBUG_LRU = localLOGV || false;
257    static final boolean DEBUG_PAUSE = localLOGV || false;
258    static final boolean DEBUG_POWER = localLOGV || false;
259    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
260    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
261    static final boolean DEBUG_PROCESSES = localLOGV || false;
262    static final boolean DEBUG_PROVIDER = localLOGV || false;
263    static final boolean DEBUG_RESULTS = localLOGV || false;
264    static final boolean DEBUG_SERVICE = localLOGV || false;
265    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
266    static final boolean DEBUG_STACK = localLOGV || false;
267    static final boolean DEBUG_SWITCH = localLOGV || false;
268    static final boolean DEBUG_TASKS = localLOGV || false;
269    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
270    static final boolean DEBUG_TRANSITION = localLOGV || false;
271    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
272    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
273    static final boolean DEBUG_VISBILITY = localLOGV || false;
274    static final boolean DEBUG_PSS = localLOGV || false;
275    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
276    static final boolean DEBUG_RECENTS = localLOGV || false;
277    static final boolean VALIDATE_TOKENS = false;
278    static final boolean SHOW_ACTIVITY_START_TIME = true;
279
280    // Control over CPU and battery monitoring.
281    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
282    static final boolean MONITOR_CPU_USAGE = true;
283    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
284    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
285    static final boolean MONITOR_THREAD_CPU_USAGE = false;
286
287    // The flags that are set for all calls we make to the package manager.
288    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
289
290    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
291
292    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
293
294    // Maximum number recent bitmaps to keep in memory.
295    static final int MAX_RECENT_BITMAPS = 5;
296
297    // Amount of time after a call to stopAppSwitches() during which we will
298    // prevent further untrusted switches from happening.
299    static final long APP_SWITCH_DELAY_TIME = 5*1000;
300
301    // How long we wait for a launched process to attach to the activity manager
302    // before we decide it's never going to come up for real.
303    static final int PROC_START_TIMEOUT = 10*1000;
304
305    // How long we wait for a launched process to attach to the activity manager
306    // before we decide it's never going to come up for real, when the process was
307    // started with a wrapper for instrumentation (such as Valgrind) because it
308    // could take much longer than usual.
309    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
310
311    // How long to wait after going idle before forcing apps to GC.
312    static final int GC_TIMEOUT = 5*1000;
313
314    // The minimum amount of time between successive GC requests for a process.
315    static final int GC_MIN_INTERVAL = 60*1000;
316
317    // The minimum amount of time between successive PSS requests for a process.
318    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
319
320    // The minimum amount of time between successive PSS requests for a process
321    // when the request is due to the memory state being lowered.
322    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
323
324    // The rate at which we check for apps using excessive power -- 15 mins.
325    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
326
327    // The minimum sample duration we will allow before deciding we have
328    // enough data on wake locks to start killing things.
329    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
330
331    // The minimum sample duration we will allow before deciding we have
332    // enough data on CPU usage to start killing things.
333    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
334
335    // How long we allow a receiver to run before giving up on it.
336    static final int BROADCAST_FG_TIMEOUT = 10*1000;
337    static final int BROADCAST_BG_TIMEOUT = 60*1000;
338
339    // How long we wait until we timeout on key dispatching.
340    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
341
342    // How long we wait until we timeout on key dispatching during instrumentation.
343    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
344
345    // Amount of time we wait for observers to handle a user switch before
346    // giving up on them and unfreezing the screen.
347    static final int USER_SWITCH_TIMEOUT = 2*1000;
348
349    // Maximum number of users we allow to be running at a time.
350    static final int MAX_RUNNING_USERS = 3;
351
352    // How long to wait in getAssistContextExtras for the activity and foreground services
353    // to respond with the result.
354    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
355
356    // Maximum number of persisted Uri grants a package is allowed
357    static final int MAX_PERSISTED_URI_GRANTS = 128;
358
359    static final int MY_PID = Process.myPid();
360
361    static final String[] EMPTY_STRING_ARRAY = new String[0];
362
363    // How many bytes to write into the dropbox log before truncating
364    static final int DROPBOX_MAX_SIZE = 256 * 1024;
365
366    // Access modes for handleIncomingUser.
367    static final int ALLOW_NON_FULL = 0;
368    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
369    static final int ALLOW_FULL_ONLY = 2;
370
371    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
372
373    /** All system services */
374    SystemServiceManager mSystemServiceManager;
375
376    private Installer mInstaller;
377
378    /** Run all ActivityStacks through this */
379    ActivityStackSupervisor mStackSupervisor;
380
381    public IntentFirewall mIntentFirewall;
382
383    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
384    // default actuion automatically.  Important for devices without direct input
385    // devices.
386    private boolean mShowDialogs = true;
387
388    BroadcastQueue mFgBroadcastQueue;
389    BroadcastQueue mBgBroadcastQueue;
390    // Convenient for easy iteration over the queues. Foreground is first
391    // so that dispatch of foreground broadcasts gets precedence.
392    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
393
394    BroadcastQueue broadcastQueueForIntent(Intent intent) {
395        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
396        if (DEBUG_BACKGROUND_BROADCAST) {
397            Slog.i(TAG, "Broadcast intent " + intent + " on "
398                    + (isFg ? "foreground" : "background")
399                    + " queue");
400        }
401        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
402    }
403
404    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
405        for (BroadcastQueue queue : mBroadcastQueues) {
406            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
407            if (r != null) {
408                return r;
409            }
410        }
411        return null;
412    }
413
414    /**
415     * Activity we have told the window manager to have key focus.
416     */
417    ActivityRecord mFocusedActivity = null;
418
419    /**
420     * List of intents that were used to start the most recent tasks.
421     */
422    ArrayList<TaskRecord> mRecentTasks;
423    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
424
425    /**
426     * For addAppTask: cached of the last activity component that was added.
427     */
428    ComponentName mLastAddedTaskComponent;
429
430    /**
431     * For addAppTask: cached of the last activity uid that was added.
432     */
433    int mLastAddedTaskUid;
434
435    /**
436     * For addAppTask: cached of the last ActivityInfo that was added.
437     */
438    ActivityInfo mLastAddedTaskActivity;
439
440    public class PendingAssistExtras extends Binder implements Runnable {
441        public final ActivityRecord activity;
442        public final Bundle extras;
443        public final Intent intent;
444        public final String hint;
445        public final int userHandle;
446        public boolean haveResult = false;
447        public Bundle result = null;
448        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
449                String _hint, int _userHandle) {
450            activity = _activity;
451            extras = _extras;
452            intent = _intent;
453            hint = _hint;
454            userHandle = _userHandle;
455        }
456        @Override
457        public void run() {
458            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
459            synchronized (this) {
460                haveResult = true;
461                notifyAll();
462            }
463        }
464    }
465
466    final ArrayList<PendingAssistExtras> mPendingAssistExtras
467            = new ArrayList<PendingAssistExtras>();
468
469    /**
470     * Process management.
471     */
472    final ProcessList mProcessList = new ProcessList();
473
474    /**
475     * All of the applications we currently have running organized by name.
476     * The keys are strings of the application package name (as
477     * returned by the package manager), and the keys are ApplicationRecord
478     * objects.
479     */
480    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
481
482    /**
483     * Tracking long-term execution of processes to look for abuse and other
484     * bad app behavior.
485     */
486    final ProcessStatsService mProcessStats;
487
488    /**
489     * The currently running isolated processes.
490     */
491    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
492
493    /**
494     * Counter for assigning isolated process uids, to avoid frequently reusing the
495     * same ones.
496     */
497    int mNextIsolatedProcessUid = 0;
498
499    /**
500     * The currently running heavy-weight process, if any.
501     */
502    ProcessRecord mHeavyWeightProcess = null;
503
504    /**
505     * The last time that various processes have crashed.
506     */
507    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
508
509    /**
510     * Information about a process that is currently marked as bad.
511     */
512    static final class BadProcessInfo {
513        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
514            this.time = time;
515            this.shortMsg = shortMsg;
516            this.longMsg = longMsg;
517            this.stack = stack;
518        }
519
520        final long time;
521        final String shortMsg;
522        final String longMsg;
523        final String stack;
524    }
525
526    /**
527     * Set of applications that we consider to be bad, and will reject
528     * incoming broadcasts from (which the user has no control over).
529     * Processes are added to this set when they have crashed twice within
530     * a minimum amount of time; they are removed from it when they are
531     * later restarted (hopefully due to some user action).  The value is the
532     * time it was added to the list.
533     */
534    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
535
536    /**
537     * All of the processes we currently have running organized by pid.
538     * The keys are the pid running the application.
539     *
540     * <p>NOTE: This object is protected by its own lock, NOT the global
541     * activity manager lock!
542     */
543    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
544
545    /**
546     * All of the processes that have been forced to be foreground.  The key
547     * is the pid of the caller who requested it (we hold a death
548     * link on it).
549     */
550    abstract class ForegroundToken implements IBinder.DeathRecipient {
551        int pid;
552        IBinder token;
553    }
554    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
555
556    /**
557     * List of records for processes that someone had tried to start before the
558     * system was ready.  We don't start them at that point, but ensure they
559     * are started by the time booting is complete.
560     */
561    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
562
563    /**
564     * List of persistent applications that are in the process
565     * of being started.
566     */
567    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
568
569    /**
570     * Processes that are being forcibly torn down.
571     */
572    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
573
574    /**
575     * List of running applications, sorted by recent usage.
576     * The first entry in the list is the least recently used.
577     */
578    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
579
580    /**
581     * Where in mLruProcesses that the processes hosting activities start.
582     */
583    int mLruProcessActivityStart = 0;
584
585    /**
586     * Where in mLruProcesses that the processes hosting services start.
587     * This is after (lower index) than mLruProcessesActivityStart.
588     */
589    int mLruProcessServiceStart = 0;
590
591    /**
592     * List of processes that should gc as soon as things are idle.
593     */
594    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
595
596    /**
597     * Processes we want to collect PSS data from.
598     */
599    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
600
601    /**
602     * Last time we requested PSS data of all processes.
603     */
604    long mLastFullPssTime = SystemClock.uptimeMillis();
605
606    /**
607     * If set, the next time we collect PSS data we should do a full collection
608     * with data from native processes and the kernel.
609     */
610    boolean mFullPssPending = false;
611
612    /**
613     * This is the process holding what we currently consider to be
614     * the "home" activity.
615     */
616    ProcessRecord mHomeProcess;
617
618    /**
619     * This is the process holding the activity the user last visited that
620     * is in a different process from the one they are currently in.
621     */
622    ProcessRecord mPreviousProcess;
623
624    /**
625     * The time at which the previous process was last visible.
626     */
627    long mPreviousProcessVisibleTime;
628
629    /**
630     * Which uses have been started, so are allowed to run code.
631     */
632    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
633
634    /**
635     * LRU list of history of current users.  Most recently current is at the end.
636     */
637    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
638
639    /**
640     * Constant array of the users that are currently started.
641     */
642    int[] mStartedUserArray = new int[] { 0 };
643
644    /**
645     * Registered observers of the user switching mechanics.
646     */
647    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
648            = new RemoteCallbackList<IUserSwitchObserver>();
649
650    /**
651     * Currently active user switch.
652     */
653    Object mCurUserSwitchCallback;
654
655    /**
656     * Packages that the user has asked to have run in screen size
657     * compatibility mode instead of filling the screen.
658     */
659    final CompatModePackages mCompatModePackages;
660
661    /**
662     * Set of IntentSenderRecord objects that are currently active.
663     */
664    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
665            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
666
667    /**
668     * Fingerprints (hashCode()) of stack traces that we've
669     * already logged DropBox entries for.  Guarded by itself.  If
670     * something (rogue user app) forces this over
671     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
672     */
673    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
674    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
675
676    /**
677     * Strict Mode background batched logging state.
678     *
679     * The string buffer is guarded by itself, and its lock is also
680     * used to determine if another batched write is already
681     * in-flight.
682     */
683    private final StringBuilder mStrictModeBuffer = new StringBuilder();
684
685    /**
686     * Keeps track of all IIntentReceivers that have been registered for
687     * broadcasts.  Hash keys are the receiver IBinder, hash value is
688     * a ReceiverList.
689     */
690    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
691            new HashMap<IBinder, ReceiverList>();
692
693    /**
694     * Resolver for broadcast intents to registered receivers.
695     * Holds BroadcastFilter (subclass of IntentFilter).
696     */
697    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
698            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
699        @Override
700        protected boolean allowFilterResult(
701                BroadcastFilter filter, List<BroadcastFilter> dest) {
702            IBinder target = filter.receiverList.receiver.asBinder();
703            for (int i=dest.size()-1; i>=0; i--) {
704                if (dest.get(i).receiverList.receiver.asBinder() == target) {
705                    return false;
706                }
707            }
708            return true;
709        }
710
711        @Override
712        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
713            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
714                    || userId == filter.owningUserId) {
715                return super.newResult(filter, match, userId);
716            }
717            return null;
718        }
719
720        @Override
721        protected BroadcastFilter[] newArray(int size) {
722            return new BroadcastFilter[size];
723        }
724
725        @Override
726        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
727            return packageName.equals(filter.packageName);
728        }
729    };
730
731    /**
732     * State of all active sticky broadcasts per user.  Keys are the action of the
733     * sticky Intent, values are an ArrayList of all broadcasted intents with
734     * that action (which should usually be one).  The SparseArray is keyed
735     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
736     * for stickies that are sent to all users.
737     */
738    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
739            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
740
741    final ActiveServices mServices;
742
743    /**
744     * Backup/restore process management
745     */
746    String mBackupAppName = null;
747    BackupRecord mBackupTarget = null;
748
749    final ProviderMap mProviderMap;
750
751    /**
752     * List of content providers who have clients waiting for them.  The
753     * application is currently being launched and the provider will be
754     * removed from this list once it is published.
755     */
756    final ArrayList<ContentProviderRecord> mLaunchingProviders
757            = new ArrayList<ContentProviderRecord>();
758
759    /**
760     * File storing persisted {@link #mGrantedUriPermissions}.
761     */
762    private final AtomicFile mGrantFile;
763
764    /** XML constants used in {@link #mGrantFile} */
765    private static final String TAG_URI_GRANTS = "uri-grants";
766    private static final String TAG_URI_GRANT = "uri-grant";
767    private static final String ATTR_USER_HANDLE = "userHandle";
768    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
769    private static final String ATTR_TARGET_USER_ID = "targetUserId";
770    private static final String ATTR_SOURCE_PKG = "sourcePkg";
771    private static final String ATTR_TARGET_PKG = "targetPkg";
772    private static final String ATTR_URI = "uri";
773    private static final String ATTR_MODE_FLAGS = "modeFlags";
774    private static final String ATTR_CREATED_TIME = "createdTime";
775    private static final String ATTR_PREFIX = "prefix";
776
777    /**
778     * Global set of specific {@link Uri} permissions that have been granted.
779     * This optimized lookup structure maps from {@link UriPermission#targetUid}
780     * to {@link UriPermission#uri} to {@link UriPermission}.
781     */
782    @GuardedBy("this")
783    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
784            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
785
786    public static class GrantUri {
787        public final int sourceUserId;
788        public final Uri uri;
789        public boolean prefix;
790
791        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
792            this.sourceUserId = sourceUserId;
793            this.uri = uri;
794            this.prefix = prefix;
795        }
796
797        @Override
798        public int hashCode() {
799            return toString().hashCode();
800        }
801
802        @Override
803        public boolean equals(Object o) {
804            if (o instanceof GrantUri) {
805                GrantUri other = (GrantUri) o;
806                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
807                        && prefix == other.prefix;
808            }
809            return false;
810        }
811
812        @Override
813        public String toString() {
814            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
815            if (prefix) result += " [prefix]";
816            return result;
817        }
818
819        public String toSafeString() {
820            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
821            if (prefix) result += " [prefix]";
822            return result;
823        }
824
825        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
826            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
827                    ContentProvider.getUriWithoutUserId(uri), false);
828        }
829    }
830
831    CoreSettingsObserver mCoreSettingsObserver;
832
833    /**
834     * Thread-local storage used to carry caller permissions over through
835     * indirect content-provider access.
836     */
837    private class Identity {
838        public int pid;
839        public int uid;
840
841        Identity(int _pid, int _uid) {
842            pid = _pid;
843            uid = _uid;
844        }
845    }
846
847    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
848
849    /**
850     * All information we have collected about the runtime performance of
851     * any user id that can impact battery performance.
852     */
853    final BatteryStatsService mBatteryStatsService;
854
855    /**
856     * Information about component usage
857     */
858    UsageStatsManagerInternal mUsageStatsService;
859
860    /**
861     * Information about and control over application operations
862     */
863    final AppOpsService mAppOpsService;
864
865    /**
866     * Save recent tasks information across reboots.
867     */
868    final TaskPersister mTaskPersister;
869
870    /**
871     * Current configuration information.  HistoryRecord objects are given
872     * a reference to this object to indicate which configuration they are
873     * currently running in, so this object must be kept immutable.
874     */
875    Configuration mConfiguration = new Configuration();
876
877    /**
878     * Current sequencing integer of the configuration, for skipping old
879     * configurations.
880     */
881    int mConfigurationSeq = 0;
882
883    /**
884     * Hardware-reported OpenGLES version.
885     */
886    final int GL_ES_VERSION;
887
888    /**
889     * List of initialization arguments to pass to all processes when binding applications to them.
890     * For example, references to the commonly used services.
891     */
892    HashMap<String, IBinder> mAppBindArgs;
893
894    /**
895     * Temporary to avoid allocations.  Protected by main lock.
896     */
897    final StringBuilder mStringBuilder = new StringBuilder(256);
898
899    /**
900     * Used to control how we initialize the service.
901     */
902    ComponentName mTopComponent;
903    String mTopAction = Intent.ACTION_MAIN;
904    String mTopData;
905    boolean mProcessesReady = false;
906    boolean mSystemReady = false;
907    boolean mBooting = false;
908    boolean mCallFinishBooting = false;
909    boolean mBootAnimationComplete = false;
910    boolean mWaitingUpdate = false;
911    boolean mDidUpdate = false;
912    boolean mOnBattery = false;
913    boolean mLaunchWarningShown = false;
914
915    Context mContext;
916
917    int mFactoryTest;
918
919    boolean mCheckedForSetup;
920
921    /**
922     * The time at which we will allow normal application switches again,
923     * after a call to {@link #stopAppSwitches()}.
924     */
925    long mAppSwitchesAllowedTime;
926
927    /**
928     * This is set to true after the first switch after mAppSwitchesAllowedTime
929     * is set; any switches after that will clear the time.
930     */
931    boolean mDidAppSwitch;
932
933    /**
934     * Last time (in realtime) at which we checked for power usage.
935     */
936    long mLastPowerCheckRealtime;
937
938    /**
939     * Last time (in uptime) at which we checked for power usage.
940     */
941    long mLastPowerCheckUptime;
942
943    /**
944     * Set while we are wanting to sleep, to prevent any
945     * activities from being started/resumed.
946     */
947    private boolean mSleeping = false;
948
949    /**
950     * Set while we are running a voice interaction.  This overrides
951     * sleeping while it is active.
952     */
953    private boolean mRunningVoice = false;
954
955    /**
956     * State of external calls telling us if the device is asleep.
957     */
958    private boolean mWentToSleep = false;
959
960    static final int LOCK_SCREEN_HIDDEN = 0;
961    static final int LOCK_SCREEN_LEAVING = 1;
962    static final int LOCK_SCREEN_SHOWN = 2;
963    /**
964     * State of external call telling us if the lock screen is shown.
965     */
966    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
967
968    /**
969     * Set if we are shutting down the system, similar to sleeping.
970     */
971    boolean mShuttingDown = false;
972
973    /**
974     * Current sequence id for oom_adj computation traversal.
975     */
976    int mAdjSeq = 0;
977
978    /**
979     * Current sequence id for process LRU updating.
980     */
981    int mLruSeq = 0;
982
983    /**
984     * Keep track of the non-cached/empty process we last found, to help
985     * determine how to distribute cached/empty processes next time.
986     */
987    int mNumNonCachedProcs = 0;
988
989    /**
990     * Keep track of the number of cached hidden procs, to balance oom adj
991     * distribution between those and empty procs.
992     */
993    int mNumCachedHiddenProcs = 0;
994
995    /**
996     * Keep track of the number of service processes we last found, to
997     * determine on the next iteration which should be B services.
998     */
999    int mNumServiceProcs = 0;
1000    int mNewNumAServiceProcs = 0;
1001    int mNewNumServiceProcs = 0;
1002
1003    /**
1004     * Allow the current computed overall memory level of the system to go down?
1005     * This is set to false when we are killing processes for reasons other than
1006     * memory management, so that the now smaller process list will not be taken as
1007     * an indication that memory is tighter.
1008     */
1009    boolean mAllowLowerMemLevel = false;
1010
1011    /**
1012     * The last computed memory level, for holding when we are in a state that
1013     * processes are going away for other reasons.
1014     */
1015    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1016
1017    /**
1018     * The last total number of process we have, to determine if changes actually look
1019     * like a shrinking number of process due to lower RAM.
1020     */
1021    int mLastNumProcesses;
1022
1023    /**
1024     * The uptime of the last time we performed idle maintenance.
1025     */
1026    long mLastIdleTime = SystemClock.uptimeMillis();
1027
1028    /**
1029     * Total time spent with RAM that has been added in the past since the last idle time.
1030     */
1031    long mLowRamTimeSinceLastIdle = 0;
1032
1033    /**
1034     * If RAM is currently low, when that horrible situation started.
1035     */
1036    long mLowRamStartTime = 0;
1037
1038    /**
1039     * For reporting to battery stats the current top application.
1040     */
1041    private String mCurResumedPackage = null;
1042    private int mCurResumedUid = -1;
1043
1044    /**
1045     * For reporting to battery stats the apps currently running foreground
1046     * service.  The ProcessMap is package/uid tuples; each of these contain
1047     * an array of the currently foreground processes.
1048     */
1049    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1050            = new ProcessMap<ArrayList<ProcessRecord>>();
1051
1052    /**
1053     * This is set if we had to do a delayed dexopt of an app before launching
1054     * it, to increase the ANR timeouts in that case.
1055     */
1056    boolean mDidDexOpt;
1057
1058    /**
1059     * Set if the systemServer made a call to enterSafeMode.
1060     */
1061    boolean mSafeMode;
1062
1063    String mDebugApp = null;
1064    boolean mWaitForDebugger = false;
1065    boolean mDebugTransient = false;
1066    String mOrigDebugApp = null;
1067    boolean mOrigWaitForDebugger = false;
1068    boolean mAlwaysFinishActivities = false;
1069    IActivityController mController = null;
1070    String mProfileApp = null;
1071    ProcessRecord mProfileProc = null;
1072    String mProfileFile;
1073    ParcelFileDescriptor mProfileFd;
1074    int mSamplingInterval = 0;
1075    boolean mAutoStopProfiler = false;
1076    int mProfileType = 0;
1077    String mOpenGlTraceApp = null;
1078
1079    static class ProcessChangeItem {
1080        static final int CHANGE_ACTIVITIES = 1<<0;
1081        static final int CHANGE_PROCESS_STATE = 1<<1;
1082        int changes;
1083        int uid;
1084        int pid;
1085        int processState;
1086        boolean foregroundActivities;
1087    }
1088
1089    final RemoteCallbackList<IProcessObserver> mProcessObservers
1090            = new RemoteCallbackList<IProcessObserver>();
1091    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1092
1093    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1094            = new ArrayList<ProcessChangeItem>();
1095    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1096            = new ArrayList<ProcessChangeItem>();
1097
1098    /**
1099     * Runtime CPU use collection thread.  This object's lock is used to
1100     * perform synchronization with the thread (notifying it to run).
1101     */
1102    final Thread mProcessCpuThread;
1103
1104    /**
1105     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1106     * Must acquire this object's lock when accessing it.
1107     * NOTE: this lock will be held while doing long operations (trawling
1108     * through all processes in /proc), so it should never be acquired by
1109     * any critical paths such as when holding the main activity manager lock.
1110     */
1111    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1112            MONITOR_THREAD_CPU_USAGE);
1113    final AtomicLong mLastCpuTime = new AtomicLong(0);
1114    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1115
1116    long mLastWriteTime = 0;
1117
1118    /**
1119     * Used to retain an update lock when the foreground activity is in
1120     * immersive mode.
1121     */
1122    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1123
1124    /**
1125     * Set to true after the system has finished booting.
1126     */
1127    boolean mBooted = false;
1128
1129    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1130    int mProcessLimitOverride = -1;
1131
1132    WindowManagerService mWindowManager;
1133
1134    final ActivityThread mSystemThread;
1135
1136    // Holds the current foreground user's id
1137    int mCurrentUserId = 0;
1138    // Holds the target user's id during a user switch
1139    int mTargetUserId = UserHandle.USER_NULL;
1140    // If there are multiple profiles for the current user, their ids are here
1141    // Currently only the primary user can have managed profiles
1142    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1143
1144    /**
1145     * Mapping from each known user ID to the profile group ID it is associated with.
1146     */
1147    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1148
1149    private UserManagerService mUserManager;
1150
1151    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1152        final ProcessRecord mApp;
1153        final int mPid;
1154        final IApplicationThread mAppThread;
1155
1156        AppDeathRecipient(ProcessRecord app, int pid,
1157                IApplicationThread thread) {
1158            if (localLOGV) Slog.v(
1159                TAG, "New death recipient " + this
1160                + " for thread " + thread.asBinder());
1161            mApp = app;
1162            mPid = pid;
1163            mAppThread = thread;
1164        }
1165
1166        @Override
1167        public void binderDied() {
1168            if (localLOGV) Slog.v(
1169                TAG, "Death received in " + this
1170                + " for thread " + mAppThread.asBinder());
1171            synchronized(ActivityManagerService.this) {
1172                appDiedLocked(mApp, mPid, mAppThread);
1173            }
1174        }
1175    }
1176
1177    static final int SHOW_ERROR_MSG = 1;
1178    static final int SHOW_NOT_RESPONDING_MSG = 2;
1179    static final int SHOW_FACTORY_ERROR_MSG = 3;
1180    static final int UPDATE_CONFIGURATION_MSG = 4;
1181    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1182    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1183    static final int SERVICE_TIMEOUT_MSG = 12;
1184    static final int UPDATE_TIME_ZONE = 13;
1185    static final int SHOW_UID_ERROR_MSG = 14;
1186    static final int IM_FEELING_LUCKY_MSG = 15;
1187    static final int PROC_START_TIMEOUT_MSG = 20;
1188    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1189    static final int KILL_APPLICATION_MSG = 22;
1190    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1191    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1192    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1193    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1194    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1195    static final int CLEAR_DNS_CACHE_MSG = 28;
1196    static final int UPDATE_HTTP_PROXY_MSG = 29;
1197    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1198    static final int DISPATCH_PROCESSES_CHANGED = 31;
1199    static final int DISPATCH_PROCESS_DIED = 32;
1200    static final int REPORT_MEM_USAGE_MSG = 33;
1201    static final int REPORT_USER_SWITCH_MSG = 34;
1202    static final int CONTINUE_USER_SWITCH_MSG = 35;
1203    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1204    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1205    static final int PERSIST_URI_GRANTS_MSG = 38;
1206    static final int REQUEST_ALL_PSS_MSG = 39;
1207    static final int START_PROFILES_MSG = 40;
1208    static final int UPDATE_TIME = 41;
1209    static final int SYSTEM_USER_START_MSG = 42;
1210    static final int SYSTEM_USER_CURRENT_MSG = 43;
1211    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1212    static final int FINISH_BOOTING_MSG = 45;
1213    static final int START_USER_SWITCH_MSG = 46;
1214    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1215
1216    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1217    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1218    static final int FIRST_COMPAT_MODE_MSG = 300;
1219    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1220
1221    AlertDialog mUidAlert;
1222    CompatModeDialog mCompatModeDialog;
1223    long mLastMemUsageReportTime = 0;
1224
1225    /**
1226     * Flag whether the current user is a "monkey", i.e. whether
1227     * the UI is driven by a UI automation tool.
1228     */
1229    private boolean mUserIsMonkey;
1230
1231    /** Flag whether the device has a Recents UI */
1232    boolean mHasRecents;
1233
1234    /** The dimensions of the thumbnails in the Recents UI. */
1235    int mThumbnailWidth;
1236    int mThumbnailHeight;
1237
1238    final ServiceThread mHandlerThread;
1239    final MainHandler mHandler;
1240
1241    final class MainHandler extends Handler {
1242        public MainHandler(Looper looper) {
1243            super(looper, null, true);
1244        }
1245
1246        @Override
1247        public void handleMessage(Message msg) {
1248            switch (msg.what) {
1249            case SHOW_ERROR_MSG: {
1250                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1251                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1252                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1253                synchronized (ActivityManagerService.this) {
1254                    ProcessRecord proc = (ProcessRecord)data.get("app");
1255                    AppErrorResult res = (AppErrorResult) data.get("result");
1256                    if (proc != null && proc.crashDialog != null) {
1257                        Slog.e(TAG, "App already has crash dialog: " + proc);
1258                        if (res != null) {
1259                            res.set(0);
1260                        }
1261                        return;
1262                    }
1263                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1264                            >= Process.FIRST_APPLICATION_UID
1265                            && proc.pid != MY_PID);
1266                    for (int userId : mCurrentProfileIds) {
1267                        isBackground &= (proc.userId != userId);
1268                    }
1269                    if (isBackground && !showBackground) {
1270                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1271                        if (res != null) {
1272                            res.set(0);
1273                        }
1274                        return;
1275                    }
1276                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1277                        Dialog d = new AppErrorDialog(mContext,
1278                                ActivityManagerService.this, res, proc);
1279                        d.show();
1280                        proc.crashDialog = d;
1281                    } else {
1282                        // The device is asleep, so just pretend that the user
1283                        // saw a crash dialog and hit "force quit".
1284                        if (res != null) {
1285                            res.set(0);
1286                        }
1287                    }
1288                }
1289
1290                ensureBootCompleted();
1291            } break;
1292            case SHOW_NOT_RESPONDING_MSG: {
1293                synchronized (ActivityManagerService.this) {
1294                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1295                    ProcessRecord proc = (ProcessRecord)data.get("app");
1296                    if (proc != null && proc.anrDialog != null) {
1297                        Slog.e(TAG, "App already has anr dialog: " + proc);
1298                        return;
1299                    }
1300
1301                    Intent intent = new Intent("android.intent.action.ANR");
1302                    if (!mProcessesReady) {
1303                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1304                                | Intent.FLAG_RECEIVER_FOREGROUND);
1305                    }
1306                    broadcastIntentLocked(null, null, intent,
1307                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1308                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1309
1310                    if (mShowDialogs) {
1311                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1312                                mContext, proc, (ActivityRecord)data.get("activity"),
1313                                msg.arg1 != 0);
1314                        d.show();
1315                        proc.anrDialog = d;
1316                    } else {
1317                        // Just kill the app if there is no dialog to be shown.
1318                        killAppAtUsersRequest(proc, null);
1319                    }
1320                }
1321
1322                ensureBootCompleted();
1323            } break;
1324            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1325                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1326                synchronized (ActivityManagerService.this) {
1327                    ProcessRecord proc = (ProcessRecord) data.get("app");
1328                    if (proc == null) {
1329                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1330                        break;
1331                    }
1332                    if (proc.crashDialog != null) {
1333                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1334                        return;
1335                    }
1336                    AppErrorResult res = (AppErrorResult) data.get("result");
1337                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1338                        Dialog d = new StrictModeViolationDialog(mContext,
1339                                ActivityManagerService.this, res, proc);
1340                        d.show();
1341                        proc.crashDialog = d;
1342                    } else {
1343                        // The device is asleep, so just pretend that the user
1344                        // saw a crash dialog and hit "force quit".
1345                        res.set(0);
1346                    }
1347                }
1348                ensureBootCompleted();
1349            } break;
1350            case SHOW_FACTORY_ERROR_MSG: {
1351                Dialog d = new FactoryErrorDialog(
1352                    mContext, msg.getData().getCharSequence("msg"));
1353                d.show();
1354                ensureBootCompleted();
1355            } break;
1356            case UPDATE_CONFIGURATION_MSG: {
1357                final ContentResolver resolver = mContext.getContentResolver();
1358                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1359            } break;
1360            case GC_BACKGROUND_PROCESSES_MSG: {
1361                synchronized (ActivityManagerService.this) {
1362                    performAppGcsIfAppropriateLocked();
1363                }
1364            } break;
1365            case WAIT_FOR_DEBUGGER_MSG: {
1366                synchronized (ActivityManagerService.this) {
1367                    ProcessRecord app = (ProcessRecord)msg.obj;
1368                    if (msg.arg1 != 0) {
1369                        if (!app.waitedForDebugger) {
1370                            Dialog d = new AppWaitingForDebuggerDialog(
1371                                    ActivityManagerService.this,
1372                                    mContext, app);
1373                            app.waitDialog = d;
1374                            app.waitedForDebugger = true;
1375                            d.show();
1376                        }
1377                    } else {
1378                        if (app.waitDialog != null) {
1379                            app.waitDialog.dismiss();
1380                            app.waitDialog = null;
1381                        }
1382                    }
1383                }
1384            } break;
1385            case SERVICE_TIMEOUT_MSG: {
1386                if (mDidDexOpt) {
1387                    mDidDexOpt = false;
1388                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1389                    nmsg.obj = msg.obj;
1390                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1391                    return;
1392                }
1393                mServices.serviceTimeout((ProcessRecord)msg.obj);
1394            } break;
1395            case UPDATE_TIME_ZONE: {
1396                synchronized (ActivityManagerService.this) {
1397                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1398                        ProcessRecord r = mLruProcesses.get(i);
1399                        if (r.thread != null) {
1400                            try {
1401                                r.thread.updateTimeZone();
1402                            } catch (RemoteException ex) {
1403                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1404                            }
1405                        }
1406                    }
1407                }
1408            } break;
1409            case CLEAR_DNS_CACHE_MSG: {
1410                synchronized (ActivityManagerService.this) {
1411                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1412                        ProcessRecord r = mLruProcesses.get(i);
1413                        if (r.thread != null) {
1414                            try {
1415                                r.thread.clearDnsCache();
1416                            } catch (RemoteException ex) {
1417                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1418                            }
1419                        }
1420                    }
1421                }
1422            } break;
1423            case UPDATE_HTTP_PROXY_MSG: {
1424                ProxyInfo proxy = (ProxyInfo)msg.obj;
1425                String host = "";
1426                String port = "";
1427                String exclList = "";
1428                Uri pacFileUrl = Uri.EMPTY;
1429                if (proxy != null) {
1430                    host = proxy.getHost();
1431                    port = Integer.toString(proxy.getPort());
1432                    exclList = proxy.getExclusionListAsString();
1433                    pacFileUrl = proxy.getPacFileUrl();
1434                }
1435                synchronized (ActivityManagerService.this) {
1436                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1437                        ProcessRecord r = mLruProcesses.get(i);
1438                        if (r.thread != null) {
1439                            try {
1440                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1441                            } catch (RemoteException ex) {
1442                                Slog.w(TAG, "Failed to update http proxy for: " +
1443                                        r.info.processName);
1444                            }
1445                        }
1446                    }
1447                }
1448            } break;
1449            case SHOW_UID_ERROR_MSG: {
1450                String title = "System UIDs Inconsistent";
1451                String text = "UIDs on the system are inconsistent, you need to wipe your"
1452                        + " data partition or your device will be unstable.";
1453                Log.e(TAG, title + ": " + text);
1454                if (mShowDialogs) {
1455                    // XXX This is a temporary dialog, no need to localize.
1456                    AlertDialog d = new BaseErrorDialog(mContext);
1457                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1458                    d.setCancelable(false);
1459                    d.setTitle(title);
1460                    d.setMessage(text);
1461                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1462                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1463                    mUidAlert = d;
1464                    d.show();
1465                }
1466            } break;
1467            case IM_FEELING_LUCKY_MSG: {
1468                if (mUidAlert != null) {
1469                    mUidAlert.dismiss();
1470                    mUidAlert = null;
1471                }
1472            } break;
1473            case PROC_START_TIMEOUT_MSG: {
1474                if (mDidDexOpt) {
1475                    mDidDexOpt = false;
1476                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1477                    nmsg.obj = msg.obj;
1478                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1479                    return;
1480                }
1481                ProcessRecord app = (ProcessRecord)msg.obj;
1482                synchronized (ActivityManagerService.this) {
1483                    processStartTimedOutLocked(app);
1484                }
1485            } break;
1486            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1487                synchronized (ActivityManagerService.this) {
1488                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1489                }
1490            } break;
1491            case KILL_APPLICATION_MSG: {
1492                synchronized (ActivityManagerService.this) {
1493                    int appid = msg.arg1;
1494                    boolean restart = (msg.arg2 == 1);
1495                    Bundle bundle = (Bundle)msg.obj;
1496                    String pkg = bundle.getString("pkg");
1497                    String reason = bundle.getString("reason");
1498                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1499                            false, UserHandle.USER_ALL, reason);
1500                }
1501            } break;
1502            case FINALIZE_PENDING_INTENT_MSG: {
1503                ((PendingIntentRecord)msg.obj).completeFinalize();
1504            } break;
1505            case POST_HEAVY_NOTIFICATION_MSG: {
1506                INotificationManager inm = NotificationManager.getService();
1507                if (inm == null) {
1508                    return;
1509                }
1510
1511                ActivityRecord root = (ActivityRecord)msg.obj;
1512                ProcessRecord process = root.app;
1513                if (process == null) {
1514                    return;
1515                }
1516
1517                try {
1518                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1519                    String text = mContext.getString(R.string.heavy_weight_notification,
1520                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1521                    Notification notification = new Notification();
1522                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1523                    notification.when = 0;
1524                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1525                    notification.tickerText = text;
1526                    notification.defaults = 0; // please be quiet
1527                    notification.sound = null;
1528                    notification.vibrate = null;
1529                    notification.color = mContext.getResources().getColor(
1530                            com.android.internal.R.color.system_notification_accent_color);
1531                    notification.setLatestEventInfo(context, text,
1532                            mContext.getText(R.string.heavy_weight_notification_detail),
1533                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1534                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1535                                    new UserHandle(root.userId)));
1536
1537                    try {
1538                        int[] outId = new int[1];
1539                        inm.enqueueNotificationWithTag("android", "android", null,
1540                                R.string.heavy_weight_notification,
1541                                notification, outId, root.userId);
1542                    } catch (RuntimeException e) {
1543                        Slog.w(ActivityManagerService.TAG,
1544                                "Error showing notification for heavy-weight app", e);
1545                    } catch (RemoteException e) {
1546                    }
1547                } catch (NameNotFoundException e) {
1548                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1549                }
1550            } break;
1551            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1552                INotificationManager inm = NotificationManager.getService();
1553                if (inm == null) {
1554                    return;
1555                }
1556                try {
1557                    inm.cancelNotificationWithTag("android", null,
1558                            R.string.heavy_weight_notification,  msg.arg1);
1559                } catch (RuntimeException e) {
1560                    Slog.w(ActivityManagerService.TAG,
1561                            "Error canceling notification for service", e);
1562                } catch (RemoteException e) {
1563                }
1564            } break;
1565            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1566                synchronized (ActivityManagerService.this) {
1567                    checkExcessivePowerUsageLocked(true);
1568                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1569                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1570                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1571                }
1572            } break;
1573            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1574                synchronized (ActivityManagerService.this) {
1575                    ActivityRecord ar = (ActivityRecord)msg.obj;
1576                    if (mCompatModeDialog != null) {
1577                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1578                                ar.info.applicationInfo.packageName)) {
1579                            return;
1580                        }
1581                        mCompatModeDialog.dismiss();
1582                        mCompatModeDialog = null;
1583                    }
1584                    if (ar != null && false) {
1585                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1586                                ar.packageName)) {
1587                            int mode = mCompatModePackages.computeCompatModeLocked(
1588                                    ar.info.applicationInfo);
1589                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1590                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1591                                mCompatModeDialog = new CompatModeDialog(
1592                                        ActivityManagerService.this, mContext,
1593                                        ar.info.applicationInfo);
1594                                mCompatModeDialog.show();
1595                            }
1596                        }
1597                    }
1598                }
1599                break;
1600            }
1601            case DISPATCH_PROCESSES_CHANGED: {
1602                dispatchProcessesChanged();
1603                break;
1604            }
1605            case DISPATCH_PROCESS_DIED: {
1606                final int pid = msg.arg1;
1607                final int uid = msg.arg2;
1608                dispatchProcessDied(pid, uid);
1609                break;
1610            }
1611            case REPORT_MEM_USAGE_MSG: {
1612                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1613                Thread thread = new Thread() {
1614                    @Override public void run() {
1615                        reportMemUsage(memInfos);
1616                    }
1617                };
1618                thread.start();
1619                break;
1620            }
1621            case START_USER_SWITCH_MSG: {
1622                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1623                break;
1624            }
1625            case REPORT_USER_SWITCH_MSG: {
1626                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1627                break;
1628            }
1629            case CONTINUE_USER_SWITCH_MSG: {
1630                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1631                break;
1632            }
1633            case USER_SWITCH_TIMEOUT_MSG: {
1634                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1635                break;
1636            }
1637            case IMMERSIVE_MODE_LOCK_MSG: {
1638                final boolean nextState = (msg.arg1 != 0);
1639                if (mUpdateLock.isHeld() != nextState) {
1640                    if (DEBUG_IMMERSIVE) {
1641                        final ActivityRecord r = (ActivityRecord) msg.obj;
1642                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1643                    }
1644                    if (nextState) {
1645                        mUpdateLock.acquire();
1646                    } else {
1647                        mUpdateLock.release();
1648                    }
1649                }
1650                break;
1651            }
1652            case PERSIST_URI_GRANTS_MSG: {
1653                writeGrantedUriPermissions();
1654                break;
1655            }
1656            case REQUEST_ALL_PSS_MSG: {
1657                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1658                break;
1659            }
1660            case START_PROFILES_MSG: {
1661                synchronized (ActivityManagerService.this) {
1662                    startProfilesLocked();
1663                }
1664                break;
1665            }
1666            case UPDATE_TIME: {
1667                synchronized (ActivityManagerService.this) {
1668                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1669                        ProcessRecord r = mLruProcesses.get(i);
1670                        if (r.thread != null) {
1671                            try {
1672                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1673                            } catch (RemoteException ex) {
1674                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1675                            }
1676                        }
1677                    }
1678                }
1679                break;
1680            }
1681            case SYSTEM_USER_START_MSG: {
1682                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1683                        Integer.toString(msg.arg1), msg.arg1);
1684                mSystemServiceManager.startUser(msg.arg1);
1685                break;
1686            }
1687            case SYSTEM_USER_CURRENT_MSG: {
1688                mBatteryStatsService.noteEvent(
1689                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1690                        Integer.toString(msg.arg2), msg.arg2);
1691                mBatteryStatsService.noteEvent(
1692                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1693                        Integer.toString(msg.arg1), msg.arg1);
1694                mSystemServiceManager.switchUser(msg.arg1);
1695                break;
1696            }
1697            case ENTER_ANIMATION_COMPLETE_MSG: {
1698                synchronized (ActivityManagerService.this) {
1699                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1700                    if (r != null && r.app != null && r.app.thread != null) {
1701                        try {
1702                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1703                        } catch (RemoteException e) {
1704                        }
1705                    }
1706                }
1707                break;
1708            }
1709            case FINISH_BOOTING_MSG: {
1710                if (msg.arg1 != 0) {
1711                    finishBooting();
1712                }
1713                if (msg.arg2 != 0) {
1714                    enableScreenAfterBoot();
1715                }
1716                break;
1717            }
1718            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1719                try {
1720                    Locale l = (Locale) msg.obj;
1721                    IBinder service = ServiceManager.getService("mount");
1722                    IMountService mountService = IMountService.Stub.asInterface(service);
1723                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1724                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1725                } catch (RemoteException e) {
1726                    Log.e(TAG, "Error storing locale for decryption UI", e);
1727                }
1728                break;
1729            }
1730            }
1731        }
1732    };
1733
1734    static final int COLLECT_PSS_BG_MSG = 1;
1735
1736    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1737        @Override
1738        public void handleMessage(Message msg) {
1739            switch (msg.what) {
1740            case COLLECT_PSS_BG_MSG: {
1741                long start = SystemClock.uptimeMillis();
1742                MemInfoReader memInfo = null;
1743                synchronized (ActivityManagerService.this) {
1744                    if (mFullPssPending) {
1745                        mFullPssPending = false;
1746                        memInfo = new MemInfoReader();
1747                    }
1748                }
1749                if (memInfo != null) {
1750                    updateCpuStatsNow();
1751                    long nativeTotalPss = 0;
1752                    synchronized (mProcessCpuTracker) {
1753                        final int N = mProcessCpuTracker.countStats();
1754                        for (int j=0; j<N; j++) {
1755                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1756                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1757                                // This is definitely an application process; skip it.
1758                                continue;
1759                            }
1760                            synchronized (mPidsSelfLocked) {
1761                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1762                                    // This is one of our own processes; skip it.
1763                                    continue;
1764                                }
1765                            }
1766                            nativeTotalPss += Debug.getPss(st.pid, null);
1767                        }
1768                    }
1769                    memInfo.readMemInfo();
1770                    synchronized (ActivityManagerService.this) {
1771                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1772                                + (SystemClock.uptimeMillis()-start) + "ms");
1773                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1774                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1775                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1776                    }
1777                }
1778
1779                int i=0, num=0;
1780                long[] tmp = new long[1];
1781                do {
1782                    ProcessRecord proc;
1783                    int procState;
1784                    int pid;
1785                    synchronized (ActivityManagerService.this) {
1786                        if (i >= mPendingPssProcesses.size()) {
1787                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1788                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1789                            mPendingPssProcesses.clear();
1790                            return;
1791                        }
1792                        proc = mPendingPssProcesses.get(i);
1793                        procState = proc.pssProcState;
1794                        if (proc.thread != null && procState == proc.setProcState) {
1795                            pid = proc.pid;
1796                        } else {
1797                            proc = null;
1798                            pid = 0;
1799                        }
1800                        i++;
1801                    }
1802                    if (proc != null) {
1803                        long pss = Debug.getPss(pid, tmp);
1804                        synchronized (ActivityManagerService.this) {
1805                            if (proc.thread != null && proc.setProcState == procState
1806                                    && proc.pid == pid) {
1807                                num++;
1808                                proc.lastPssTime = SystemClock.uptimeMillis();
1809                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1810                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1811                                        + ": " + pss + " lastPss=" + proc.lastPss
1812                                        + " state=" + ProcessList.makeProcStateString(procState));
1813                                if (proc.initialIdlePss == 0) {
1814                                    proc.initialIdlePss = pss;
1815                                }
1816                                proc.lastPss = pss;
1817                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1818                                    proc.lastCachedPss = pss;
1819                                }
1820                            }
1821                        }
1822                    }
1823                } while (true);
1824            }
1825            }
1826        }
1827    };
1828
1829    /**
1830     * Monitor for package changes and update our internal state.
1831     */
1832    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1833        @Override
1834        public void onPackageRemoved(String packageName, int uid) {
1835            // Remove all tasks with activities in the specified package from the list of recent tasks
1836            final int eventUserId = getChangingUserId();
1837            synchronized (ActivityManagerService.this) {
1838                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1839                    TaskRecord tr = mRecentTasks.get(i);
1840                    if (tr.userId != eventUserId) continue;
1841
1842                    ComponentName cn = tr.intent.getComponent();
1843                    if (cn != null && cn.getPackageName().equals(packageName)) {
1844                        // If the package name matches, remove the task
1845                        removeTaskByIdLocked(tr.taskId, true);
1846                    }
1847                }
1848            }
1849        }
1850
1851        @Override
1852        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1853            onPackageModified(packageName);
1854            return true;
1855        }
1856
1857        @Override
1858        public void onPackageModified(String packageName) {
1859            final int eventUserId = getChangingUserId();
1860            final IPackageManager pm = AppGlobals.getPackageManager();
1861            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1862                    new ArrayList<Pair<Intent, Integer>>();
1863            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
1864            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1865            // Copy the list of recent tasks so that we don't hold onto the lock on
1866            // ActivityManagerService for long periods while checking if components exist.
1867            synchronized (ActivityManagerService.this) {
1868                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1869                    TaskRecord tr = mRecentTasks.get(i);
1870                    if (tr.userId != eventUserId) continue;
1871
1872                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1873                }
1874            }
1875            // Check the recent tasks and filter out all tasks with components that no longer exist.
1876            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1877                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1878                ComponentName cn = p.first.getComponent();
1879                if (cn != null && cn.getPackageName().equals(packageName)) {
1880                    if (componentsKnownToExist.contains(cn)) {
1881                        // If we know that the component still exists in the package, then skip
1882                        continue;
1883                    }
1884                    try {
1885                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
1886                        if (info != null) {
1887                            componentsKnownToExist.add(cn);
1888                        } else {
1889                            tasksToRemove.add(p.second);
1890                        }
1891                    } catch (RemoteException e) {
1892                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
1893                    }
1894                }
1895            }
1896            // Prune all the tasks with removed components from the list of recent tasks
1897            synchronized (ActivityManagerService.this) {
1898                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1899                    removeTaskByIdLocked(tasksToRemove.get(i), false);
1900                }
1901            }
1902        }
1903
1904        @Override
1905        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1906            // Force stop the specified packages
1907            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
1908            if (packages != null) {
1909                for (String pkg : packages) {
1910                    synchronized (ActivityManagerService.this) {
1911                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
1912                                userId, "finished booting")) {
1913                            return true;
1914                        }
1915                    }
1916                }
1917            }
1918            return false;
1919        }
1920    };
1921
1922    public void setSystemProcess() {
1923        try {
1924            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1925            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1926            ServiceManager.addService("meminfo", new MemBinder(this));
1927            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1928            ServiceManager.addService("dbinfo", new DbBinder(this));
1929            if (MONITOR_CPU_USAGE) {
1930                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1931            }
1932            ServiceManager.addService("permission", new PermissionController(this));
1933
1934            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1935                    "android", STOCK_PM_FLAGS);
1936            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1937
1938            synchronized (this) {
1939                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1940                app.persistent = true;
1941                app.pid = MY_PID;
1942                app.maxAdj = ProcessList.SYSTEM_ADJ;
1943                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1944                mProcessNames.put(app.processName, app.uid, app);
1945                synchronized (mPidsSelfLocked) {
1946                    mPidsSelfLocked.put(app.pid, app);
1947                }
1948                updateLruProcessLocked(app, false, null);
1949                updateOomAdjLocked();
1950            }
1951        } catch (PackageManager.NameNotFoundException e) {
1952            throw new RuntimeException(
1953                    "Unable to find android system package", e);
1954        }
1955    }
1956
1957    public void setWindowManager(WindowManagerService wm) {
1958        mWindowManager = wm;
1959        mStackSupervisor.setWindowManager(wm);
1960    }
1961
1962    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1963        mUsageStatsService = usageStatsManager;
1964    }
1965
1966    public void startObservingNativeCrashes() {
1967        final NativeCrashListener ncl = new NativeCrashListener(this);
1968        ncl.start();
1969    }
1970
1971    public IAppOpsService getAppOpsService() {
1972        return mAppOpsService;
1973    }
1974
1975    static class MemBinder extends Binder {
1976        ActivityManagerService mActivityManagerService;
1977        MemBinder(ActivityManagerService activityManagerService) {
1978            mActivityManagerService = activityManagerService;
1979        }
1980
1981        @Override
1982        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1983            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1984                    != PackageManager.PERMISSION_GRANTED) {
1985                pw.println("Permission Denial: can't dump meminfo from from pid="
1986                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1987                        + " without permission " + android.Manifest.permission.DUMP);
1988                return;
1989            }
1990
1991            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1992        }
1993    }
1994
1995    static class GraphicsBinder extends Binder {
1996        ActivityManagerService mActivityManagerService;
1997        GraphicsBinder(ActivityManagerService activityManagerService) {
1998            mActivityManagerService = activityManagerService;
1999        }
2000
2001        @Override
2002        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2003            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2004                    != PackageManager.PERMISSION_GRANTED) {
2005                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2006                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2007                        + " without permission " + android.Manifest.permission.DUMP);
2008                return;
2009            }
2010
2011            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2012        }
2013    }
2014
2015    static class DbBinder extends Binder {
2016        ActivityManagerService mActivityManagerService;
2017        DbBinder(ActivityManagerService activityManagerService) {
2018            mActivityManagerService = activityManagerService;
2019        }
2020
2021        @Override
2022        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2023            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2024                    != PackageManager.PERMISSION_GRANTED) {
2025                pw.println("Permission Denial: can't dump dbinfo from from pid="
2026                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2027                        + " without permission " + android.Manifest.permission.DUMP);
2028                return;
2029            }
2030
2031            mActivityManagerService.dumpDbInfo(fd, pw, args);
2032        }
2033    }
2034
2035    static class CpuBinder extends Binder {
2036        ActivityManagerService mActivityManagerService;
2037        CpuBinder(ActivityManagerService activityManagerService) {
2038            mActivityManagerService = activityManagerService;
2039        }
2040
2041        @Override
2042        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2043            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2044                    != PackageManager.PERMISSION_GRANTED) {
2045                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2046                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2047                        + " without permission " + android.Manifest.permission.DUMP);
2048                return;
2049            }
2050
2051            synchronized (mActivityManagerService.mProcessCpuTracker) {
2052                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2053                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2054                        SystemClock.uptimeMillis()));
2055            }
2056        }
2057    }
2058
2059    public static final class Lifecycle extends SystemService {
2060        private final ActivityManagerService mService;
2061
2062        public Lifecycle(Context context) {
2063            super(context);
2064            mService = new ActivityManagerService(context);
2065        }
2066
2067        @Override
2068        public void onStart() {
2069            mService.start();
2070        }
2071
2072        public ActivityManagerService getService() {
2073            return mService;
2074        }
2075    }
2076
2077    // Note: This method is invoked on the main thread but may need to attach various
2078    // handlers to other threads.  So take care to be explicit about the looper.
2079    public ActivityManagerService(Context systemContext) {
2080        mContext = systemContext;
2081        mFactoryTest = FactoryTest.getMode();
2082        mSystemThread = ActivityThread.currentActivityThread();
2083
2084        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2085
2086        mHandlerThread = new ServiceThread(TAG,
2087                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2088        mHandlerThread.start();
2089        mHandler = new MainHandler(mHandlerThread.getLooper());
2090
2091        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2092                "foreground", BROADCAST_FG_TIMEOUT, false);
2093        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2094                "background", BROADCAST_BG_TIMEOUT, true);
2095        mBroadcastQueues[0] = mFgBroadcastQueue;
2096        mBroadcastQueues[1] = mBgBroadcastQueue;
2097
2098        mServices = new ActiveServices(this);
2099        mProviderMap = new ProviderMap(this);
2100
2101        // TODO: Move creation of battery stats service outside of activity manager service.
2102        File dataDir = Environment.getDataDirectory();
2103        File systemDir = new File(dataDir, "system");
2104        systemDir.mkdirs();
2105        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2106        mBatteryStatsService.getActiveStatistics().readLocked();
2107        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2108        mOnBattery = DEBUG_POWER ? true
2109                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2110        mBatteryStatsService.getActiveStatistics().setCallback(this);
2111
2112        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2113
2114        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2115
2116        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2117
2118        // User 0 is the first and only user that runs at boot.
2119        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2120        mUserLru.add(Integer.valueOf(0));
2121        updateStartedUserArrayLocked();
2122
2123        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2124            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2125
2126        mConfiguration.setToDefaults();
2127        mConfiguration.setLocale(Locale.getDefault());
2128
2129        mConfigurationSeq = mConfiguration.seq = 1;
2130        mProcessCpuTracker.init();
2131
2132        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2133        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2134        mStackSupervisor = new ActivityStackSupervisor(this);
2135        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2136
2137        mProcessCpuThread = new Thread("CpuTracker") {
2138            @Override
2139            public void run() {
2140                while (true) {
2141                    try {
2142                        try {
2143                            synchronized(this) {
2144                                final long now = SystemClock.uptimeMillis();
2145                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2146                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2147                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2148                                //        + ", write delay=" + nextWriteDelay);
2149                                if (nextWriteDelay < nextCpuDelay) {
2150                                    nextCpuDelay = nextWriteDelay;
2151                                }
2152                                if (nextCpuDelay > 0) {
2153                                    mProcessCpuMutexFree.set(true);
2154                                    this.wait(nextCpuDelay);
2155                                }
2156                            }
2157                        } catch (InterruptedException e) {
2158                        }
2159                        updateCpuStatsNow();
2160                    } catch (Exception e) {
2161                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2162                    }
2163                }
2164            }
2165        };
2166
2167        Watchdog.getInstance().addMonitor(this);
2168        Watchdog.getInstance().addThread(mHandler);
2169    }
2170
2171    public void setSystemServiceManager(SystemServiceManager mgr) {
2172        mSystemServiceManager = mgr;
2173    }
2174
2175    public void setInstaller(Installer installer) {
2176        mInstaller = installer;
2177    }
2178
2179    private void start() {
2180        Process.removeAllProcessGroups();
2181        mProcessCpuThread.start();
2182
2183        mBatteryStatsService.publish(mContext);
2184        mAppOpsService.publish(mContext);
2185        Slog.d("AppOps", "AppOpsService published");
2186        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2187    }
2188
2189    public void initPowerManagement() {
2190        mStackSupervisor.initPowerManagement();
2191        mBatteryStatsService.initPowerManagement();
2192    }
2193
2194    @Override
2195    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2196            throws RemoteException {
2197        if (code == SYSPROPS_TRANSACTION) {
2198            // We need to tell all apps about the system property change.
2199            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2200            synchronized(this) {
2201                final int NP = mProcessNames.getMap().size();
2202                for (int ip=0; ip<NP; ip++) {
2203                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2204                    final int NA = apps.size();
2205                    for (int ia=0; ia<NA; ia++) {
2206                        ProcessRecord app = apps.valueAt(ia);
2207                        if (app.thread != null) {
2208                            procs.add(app.thread.asBinder());
2209                        }
2210                    }
2211                }
2212            }
2213
2214            int N = procs.size();
2215            for (int i=0; i<N; i++) {
2216                Parcel data2 = Parcel.obtain();
2217                try {
2218                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2219                } catch (RemoteException e) {
2220                }
2221                data2.recycle();
2222            }
2223        }
2224        try {
2225            return super.onTransact(code, data, reply, flags);
2226        } catch (RuntimeException e) {
2227            // The activity manager only throws security exceptions, so let's
2228            // log all others.
2229            if (!(e instanceof SecurityException)) {
2230                Slog.wtf(TAG, "Activity Manager Crash", e);
2231            }
2232            throw e;
2233        }
2234    }
2235
2236    void updateCpuStats() {
2237        final long now = SystemClock.uptimeMillis();
2238        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2239            return;
2240        }
2241        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2242            synchronized (mProcessCpuThread) {
2243                mProcessCpuThread.notify();
2244            }
2245        }
2246    }
2247
2248    void updateCpuStatsNow() {
2249        synchronized (mProcessCpuTracker) {
2250            mProcessCpuMutexFree.set(false);
2251            final long now = SystemClock.uptimeMillis();
2252            boolean haveNewCpuStats = false;
2253
2254            if (MONITOR_CPU_USAGE &&
2255                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2256                mLastCpuTime.set(now);
2257                haveNewCpuStats = true;
2258                mProcessCpuTracker.update();
2259                //Slog.i(TAG, mProcessCpu.printCurrentState());
2260                //Slog.i(TAG, "Total CPU usage: "
2261                //        + mProcessCpu.getTotalCpuPercent() + "%");
2262
2263                // Slog the cpu usage if the property is set.
2264                if ("true".equals(SystemProperties.get("events.cpu"))) {
2265                    int user = mProcessCpuTracker.getLastUserTime();
2266                    int system = mProcessCpuTracker.getLastSystemTime();
2267                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2268                    int irq = mProcessCpuTracker.getLastIrqTime();
2269                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2270                    int idle = mProcessCpuTracker.getLastIdleTime();
2271
2272                    int total = user + system + iowait + irq + softIrq + idle;
2273                    if (total == 0) total = 1;
2274
2275                    EventLog.writeEvent(EventLogTags.CPU,
2276                            ((user+system+iowait+irq+softIrq) * 100) / total,
2277                            (user * 100) / total,
2278                            (system * 100) / total,
2279                            (iowait * 100) / total,
2280                            (irq * 100) / total,
2281                            (softIrq * 100) / total);
2282                }
2283            }
2284
2285            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2286            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2287            synchronized(bstats) {
2288                synchronized(mPidsSelfLocked) {
2289                    if (haveNewCpuStats) {
2290                        if (mOnBattery) {
2291                            int perc = bstats.startAddingCpuLocked();
2292                            int totalUTime = 0;
2293                            int totalSTime = 0;
2294                            final int N = mProcessCpuTracker.countStats();
2295                            for (int i=0; i<N; i++) {
2296                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2297                                if (!st.working) {
2298                                    continue;
2299                                }
2300                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2301                                int otherUTime = (st.rel_utime*perc)/100;
2302                                int otherSTime = (st.rel_stime*perc)/100;
2303                                totalUTime += otherUTime;
2304                                totalSTime += otherSTime;
2305                                if (pr != null) {
2306                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2307                                    if (ps == null || !ps.isActive()) {
2308                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2309                                                pr.info.uid, pr.processName);
2310                                    }
2311                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2312                                            st.rel_stime-otherSTime);
2313                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2314                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2315                                } else {
2316                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2317                                    if (ps == null || !ps.isActive()) {
2318                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2319                                                bstats.mapUid(st.uid), st.name);
2320                                    }
2321                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2322                                            st.rel_stime-otherSTime);
2323                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2324                                }
2325                            }
2326                            bstats.finishAddingCpuLocked(perc, totalUTime,
2327                                    totalSTime, cpuSpeedTimes);
2328                        }
2329                    }
2330                }
2331
2332                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2333                    mLastWriteTime = now;
2334                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2335                }
2336            }
2337        }
2338    }
2339
2340    @Override
2341    public void batteryNeedsCpuUpdate() {
2342        updateCpuStatsNow();
2343    }
2344
2345    @Override
2346    public void batteryPowerChanged(boolean onBattery) {
2347        // When plugging in, update the CPU stats first before changing
2348        // the plug state.
2349        updateCpuStatsNow();
2350        synchronized (this) {
2351            synchronized(mPidsSelfLocked) {
2352                mOnBattery = DEBUG_POWER ? true : onBattery;
2353            }
2354        }
2355    }
2356
2357    /**
2358     * Initialize the application bind args. These are passed to each
2359     * process when the bindApplication() IPC is sent to the process. They're
2360     * lazily setup to make sure the services are running when they're asked for.
2361     */
2362    private HashMap<String, IBinder> getCommonServicesLocked() {
2363        if (mAppBindArgs == null) {
2364            mAppBindArgs = new HashMap<String, IBinder>();
2365
2366            // Setup the application init args
2367            mAppBindArgs.put("package", ServiceManager.getService("package"));
2368            mAppBindArgs.put("window", ServiceManager.getService("window"));
2369            mAppBindArgs.put(Context.ALARM_SERVICE,
2370                    ServiceManager.getService(Context.ALARM_SERVICE));
2371        }
2372        return mAppBindArgs;
2373    }
2374
2375    final void setFocusedActivityLocked(ActivityRecord r) {
2376        if (mFocusedActivity != r) {
2377            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2378            mFocusedActivity = r;
2379            if (r.task != null && r.task.voiceInteractor != null) {
2380                startRunningVoiceLocked();
2381            } else {
2382                finishRunningVoiceLocked();
2383            }
2384            mStackSupervisor.setFocusedStack(r);
2385            if (r != null) {
2386                mWindowManager.setFocusedApp(r.appToken, true);
2387            }
2388            applyUpdateLockStateLocked(r);
2389        }
2390    }
2391
2392    final void clearFocusedActivity(ActivityRecord r) {
2393        if (mFocusedActivity == r) {
2394            mFocusedActivity = null;
2395        }
2396    }
2397
2398    @Override
2399    public void setFocusedStack(int stackId) {
2400        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2401        synchronized (ActivityManagerService.this) {
2402            ActivityStack stack = mStackSupervisor.getStack(stackId);
2403            if (stack != null) {
2404                ActivityRecord r = stack.topRunningActivityLocked(null);
2405                if (r != null) {
2406                    setFocusedActivityLocked(r);
2407                }
2408            }
2409        }
2410    }
2411
2412    @Override
2413    public void notifyActivityDrawn(IBinder token) {
2414        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2415        synchronized (this) {
2416            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2417            if (r != null) {
2418                r.task.stack.notifyActivityDrawnLocked(r);
2419            }
2420        }
2421    }
2422
2423    final void applyUpdateLockStateLocked(ActivityRecord r) {
2424        // Modifications to the UpdateLock state are done on our handler, outside
2425        // the activity manager's locks.  The new state is determined based on the
2426        // state *now* of the relevant activity record.  The object is passed to
2427        // the handler solely for logging detail, not to be consulted/modified.
2428        final boolean nextState = r != null && r.immersive;
2429        mHandler.sendMessage(
2430                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2431    }
2432
2433    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2434        Message msg = Message.obtain();
2435        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2436        msg.obj = r.task.askedCompatMode ? null : r;
2437        mHandler.sendMessage(msg);
2438    }
2439
2440    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2441            String what, Object obj, ProcessRecord srcApp) {
2442        app.lastActivityTime = now;
2443
2444        if (app.activities.size() > 0) {
2445            // Don't want to touch dependent processes that are hosting activities.
2446            return index;
2447        }
2448
2449        int lrui = mLruProcesses.lastIndexOf(app);
2450        if (lrui < 0) {
2451            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2452                    + what + " " + obj + " from " + srcApp);
2453            return index;
2454        }
2455
2456        if (lrui >= index) {
2457            // Don't want to cause this to move dependent processes *back* in the
2458            // list as if they were less frequently used.
2459            return index;
2460        }
2461
2462        if (lrui >= mLruProcessActivityStart) {
2463            // Don't want to touch dependent processes that are hosting activities.
2464            return index;
2465        }
2466
2467        mLruProcesses.remove(lrui);
2468        if (index > 0) {
2469            index--;
2470        }
2471        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2472                + " in LRU list: " + app);
2473        mLruProcesses.add(index, app);
2474        return index;
2475    }
2476
2477    final void removeLruProcessLocked(ProcessRecord app) {
2478        int lrui = mLruProcesses.lastIndexOf(app);
2479        if (lrui >= 0) {
2480            if (!app.killed) {
2481                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2482                Process.killProcessQuiet(app.pid);
2483                Process.killProcessGroup(app.info.uid, app.pid);
2484            }
2485            if (lrui <= mLruProcessActivityStart) {
2486                mLruProcessActivityStart--;
2487            }
2488            if (lrui <= mLruProcessServiceStart) {
2489                mLruProcessServiceStart--;
2490            }
2491            mLruProcesses.remove(lrui);
2492        }
2493    }
2494
2495    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2496            ProcessRecord client) {
2497        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2498                || app.treatLikeActivity;
2499        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2500        if (!activityChange && hasActivity) {
2501            // The process has activities, so we are only allowing activity-based adjustments
2502            // to move it.  It should be kept in the front of the list with other
2503            // processes that have activities, and we don't want those to change their
2504            // order except due to activity operations.
2505            return;
2506        }
2507
2508        mLruSeq++;
2509        final long now = SystemClock.uptimeMillis();
2510        app.lastActivityTime = now;
2511
2512        // First a quick reject: if the app is already at the position we will
2513        // put it, then there is nothing to do.
2514        if (hasActivity) {
2515            final int N = mLruProcesses.size();
2516            if (N > 0 && mLruProcesses.get(N-1) == app) {
2517                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2518                return;
2519            }
2520        } else {
2521            if (mLruProcessServiceStart > 0
2522                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2523                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2524                return;
2525            }
2526        }
2527
2528        int lrui = mLruProcesses.lastIndexOf(app);
2529
2530        if (app.persistent && lrui >= 0) {
2531            // We don't care about the position of persistent processes, as long as
2532            // they are in the list.
2533            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2534            return;
2535        }
2536
2537        /* In progress: compute new position first, so we can avoid doing work
2538           if the process is not actually going to move.  Not yet working.
2539        int addIndex;
2540        int nextIndex;
2541        boolean inActivity = false, inService = false;
2542        if (hasActivity) {
2543            // Process has activities, put it at the very tipsy-top.
2544            addIndex = mLruProcesses.size();
2545            nextIndex = mLruProcessServiceStart;
2546            inActivity = true;
2547        } else if (hasService) {
2548            // Process has services, put it at the top of the service list.
2549            addIndex = mLruProcessActivityStart;
2550            nextIndex = mLruProcessServiceStart;
2551            inActivity = true;
2552            inService = true;
2553        } else  {
2554            // Process not otherwise of interest, it goes to the top of the non-service area.
2555            addIndex = mLruProcessServiceStart;
2556            if (client != null) {
2557                int clientIndex = mLruProcesses.lastIndexOf(client);
2558                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2559                        + app);
2560                if (clientIndex >= 0 && addIndex > clientIndex) {
2561                    addIndex = clientIndex;
2562                }
2563            }
2564            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2565        }
2566
2567        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2568                + mLruProcessActivityStart + "): " + app);
2569        */
2570
2571        if (lrui >= 0) {
2572            if (lrui < mLruProcessActivityStart) {
2573                mLruProcessActivityStart--;
2574            }
2575            if (lrui < mLruProcessServiceStart) {
2576                mLruProcessServiceStart--;
2577            }
2578            /*
2579            if (addIndex > lrui) {
2580                addIndex--;
2581            }
2582            if (nextIndex > lrui) {
2583                nextIndex--;
2584            }
2585            */
2586            mLruProcesses.remove(lrui);
2587        }
2588
2589        /*
2590        mLruProcesses.add(addIndex, app);
2591        if (inActivity) {
2592            mLruProcessActivityStart++;
2593        }
2594        if (inService) {
2595            mLruProcessActivityStart++;
2596        }
2597        */
2598
2599        int nextIndex;
2600        if (hasActivity) {
2601            final int N = mLruProcesses.size();
2602            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2603                // Process doesn't have activities, but has clients with
2604                // activities...  move it up, but one below the top (the top
2605                // should always have a real activity).
2606                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2607                mLruProcesses.add(N-1, app);
2608                // To keep it from spamming the LRU list (by making a bunch of clients),
2609                // we will push down any other entries owned by the app.
2610                final int uid = app.info.uid;
2611                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2612                    ProcessRecord subProc = mLruProcesses.get(i);
2613                    if (subProc.info.uid == uid) {
2614                        // We want to push this one down the list.  If the process after
2615                        // it is for the same uid, however, don't do so, because we don't
2616                        // want them internally to be re-ordered.
2617                        if (mLruProcesses.get(i-1).info.uid != uid) {
2618                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2619                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2620                            ProcessRecord tmp = mLruProcesses.get(i);
2621                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2622                            mLruProcesses.set(i-1, tmp);
2623                            i--;
2624                        }
2625                    } else {
2626                        // A gap, we can stop here.
2627                        break;
2628                    }
2629                }
2630            } else {
2631                // Process has activities, put it at the very tipsy-top.
2632                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2633                mLruProcesses.add(app);
2634            }
2635            nextIndex = mLruProcessServiceStart;
2636        } else if (hasService) {
2637            // Process has services, put it at the top of the service list.
2638            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2639            mLruProcesses.add(mLruProcessActivityStart, app);
2640            nextIndex = mLruProcessServiceStart;
2641            mLruProcessActivityStart++;
2642        } else  {
2643            // Process not otherwise of interest, it goes to the top of the non-service area.
2644            int index = mLruProcessServiceStart;
2645            if (client != null) {
2646                // If there is a client, don't allow the process to be moved up higher
2647                // in the list than that client.
2648                int clientIndex = mLruProcesses.lastIndexOf(client);
2649                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2650                        + " when updating " + app);
2651                if (clientIndex <= lrui) {
2652                    // Don't allow the client index restriction to push it down farther in the
2653                    // list than it already is.
2654                    clientIndex = lrui;
2655                }
2656                if (clientIndex >= 0 && index > clientIndex) {
2657                    index = clientIndex;
2658                }
2659            }
2660            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2661            mLruProcesses.add(index, app);
2662            nextIndex = index-1;
2663            mLruProcessActivityStart++;
2664            mLruProcessServiceStart++;
2665        }
2666
2667        // If the app is currently using a content provider or service,
2668        // bump those processes as well.
2669        for (int j=app.connections.size()-1; j>=0; j--) {
2670            ConnectionRecord cr = app.connections.valueAt(j);
2671            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2672                    && cr.binding.service.app != null
2673                    && cr.binding.service.app.lruSeq != mLruSeq
2674                    && !cr.binding.service.app.persistent) {
2675                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2676                        "service connection", cr, app);
2677            }
2678        }
2679        for (int j=app.conProviders.size()-1; j>=0; j--) {
2680            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2681            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2682                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2683                        "provider reference", cpr, app);
2684            }
2685        }
2686    }
2687
2688    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2689        if (uid == Process.SYSTEM_UID) {
2690            // The system gets to run in any process.  If there are multiple
2691            // processes with the same uid, just pick the first (this
2692            // should never happen).
2693            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2694            if (procs == null) return null;
2695            final int N = procs.size();
2696            for (int i = 0; i < N; i++) {
2697                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2698            }
2699        }
2700        ProcessRecord proc = mProcessNames.get(processName, uid);
2701        if (false && proc != null && !keepIfLarge
2702                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2703                && proc.lastCachedPss >= 4000) {
2704            // Turn this condition on to cause killing to happen regularly, for testing.
2705            if (proc.baseProcessTracker != null) {
2706                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2707            }
2708            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2709        } else if (proc != null && !keepIfLarge
2710                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2711                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2712            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2713            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2714                if (proc.baseProcessTracker != null) {
2715                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2716                }
2717                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2718            }
2719        }
2720        return proc;
2721    }
2722
2723    void ensurePackageDexOpt(String packageName) {
2724        IPackageManager pm = AppGlobals.getPackageManager();
2725        try {
2726            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2727                mDidDexOpt = true;
2728            }
2729        } catch (RemoteException e) {
2730        }
2731    }
2732
2733    boolean isNextTransitionForward() {
2734        int transit = mWindowManager.getPendingAppTransition();
2735        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2736                || transit == AppTransition.TRANSIT_TASK_OPEN
2737                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2738    }
2739
2740    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2741            String processName, String abiOverride, int uid, Runnable crashHandler) {
2742        synchronized(this) {
2743            ApplicationInfo info = new ApplicationInfo();
2744            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2745            // For isolated processes, the former contains the parent's uid and the latter the
2746            // actual uid of the isolated process.
2747            // In the special case introduced by this method (which is, starting an isolated
2748            // process directly from the SystemServer without an actual parent app process) the
2749            // closest thing to a parent's uid is SYSTEM_UID.
2750            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2751            // the |isolated| logic in the ProcessRecord constructor.
2752            info.uid = Process.SYSTEM_UID;
2753            info.processName = processName;
2754            info.className = entryPoint;
2755            info.packageName = "android";
2756            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2757                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2758                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2759                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2760                    crashHandler);
2761            return proc != null ? proc.pid : 0;
2762        }
2763    }
2764
2765    final ProcessRecord startProcessLocked(String processName,
2766            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2767            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2768            boolean isolated, boolean keepIfLarge) {
2769        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2770                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2771                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2772                null /* crashHandler */);
2773    }
2774
2775    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2776            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2777            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2778            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2779        long startTime = SystemClock.elapsedRealtime();
2780        ProcessRecord app;
2781        if (!isolated) {
2782            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2783            checkTime(startTime, "startProcess: after getProcessRecord");
2784        } else {
2785            // If this is an isolated process, it can't re-use an existing process.
2786            app = null;
2787        }
2788        // We don't have to do anything more if:
2789        // (1) There is an existing application record; and
2790        // (2) The caller doesn't think it is dead, OR there is no thread
2791        //     object attached to it so we know it couldn't have crashed; and
2792        // (3) There is a pid assigned to it, so it is either starting or
2793        //     already running.
2794        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2795                + " app=" + app + " knownToBeDead=" + knownToBeDead
2796                + " thread=" + (app != null ? app.thread : null)
2797                + " pid=" + (app != null ? app.pid : -1));
2798        if (app != null && app.pid > 0) {
2799            if (!knownToBeDead || app.thread == null) {
2800                // We already have the app running, or are waiting for it to
2801                // come up (we have a pid but not yet its thread), so keep it.
2802                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2803                // If this is a new package in the process, add the package to the list
2804                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2805                checkTime(startTime, "startProcess: done, added package to proc");
2806                return app;
2807            }
2808
2809            // An application record is attached to a previous process,
2810            // clean it up now.
2811            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2812            checkTime(startTime, "startProcess: bad proc running, killing");
2813            Process.killProcessGroup(app.info.uid, app.pid);
2814            handleAppDiedLocked(app, true, true);
2815            checkTime(startTime, "startProcess: done killing old proc");
2816        }
2817
2818        String hostingNameStr = hostingName != null
2819                ? hostingName.flattenToShortString() : null;
2820
2821        if (!isolated) {
2822            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2823                // If we are in the background, then check to see if this process
2824                // is bad.  If so, we will just silently fail.
2825                if (mBadProcesses.get(info.processName, info.uid) != null) {
2826                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2827                            + "/" + info.processName);
2828                    return null;
2829                }
2830            } else {
2831                // When the user is explicitly starting a process, then clear its
2832                // crash count so that we won't make it bad until they see at
2833                // least one crash dialog again, and make the process good again
2834                // if it had been bad.
2835                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2836                        + "/" + info.processName);
2837                mProcessCrashTimes.remove(info.processName, info.uid);
2838                if (mBadProcesses.get(info.processName, info.uid) != null) {
2839                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2840                            UserHandle.getUserId(info.uid), info.uid,
2841                            info.processName);
2842                    mBadProcesses.remove(info.processName, info.uid);
2843                    if (app != null) {
2844                        app.bad = false;
2845                    }
2846                }
2847            }
2848        }
2849
2850        if (app == null) {
2851            checkTime(startTime, "startProcess: creating new process record");
2852            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2853            app.crashHandler = crashHandler;
2854            if (app == null) {
2855                Slog.w(TAG, "Failed making new process record for "
2856                        + processName + "/" + info.uid + " isolated=" + isolated);
2857                return null;
2858            }
2859            mProcessNames.put(processName, app.uid, app);
2860            if (isolated) {
2861                mIsolatedProcesses.put(app.uid, app);
2862            }
2863            checkTime(startTime, "startProcess: done creating new process record");
2864        } else {
2865            // If this is a new package in the process, add the package to the list
2866            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2867            checkTime(startTime, "startProcess: added package to existing proc");
2868        }
2869
2870        // If the system is not ready yet, then hold off on starting this
2871        // process until it is.
2872        if (!mProcessesReady
2873                && !isAllowedWhileBooting(info)
2874                && !allowWhileBooting) {
2875            if (!mProcessesOnHold.contains(app)) {
2876                mProcessesOnHold.add(app);
2877            }
2878            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2879            checkTime(startTime, "startProcess: returning with proc on hold");
2880            return app;
2881        }
2882
2883        checkTime(startTime, "startProcess: stepping in to startProcess");
2884        startProcessLocked(
2885                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2886        checkTime(startTime, "startProcess: done starting proc!");
2887        return (app.pid != 0) ? app : null;
2888    }
2889
2890    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2891        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2892    }
2893
2894    private final void startProcessLocked(ProcessRecord app,
2895            String hostingType, String hostingNameStr) {
2896        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2897                null /* entryPoint */, null /* entryPointArgs */);
2898    }
2899
2900    private final void startProcessLocked(ProcessRecord app, String hostingType,
2901            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2902        long startTime = SystemClock.elapsedRealtime();
2903        if (app.pid > 0 && app.pid != MY_PID) {
2904            checkTime(startTime, "startProcess: removing from pids map");
2905            synchronized (mPidsSelfLocked) {
2906                mPidsSelfLocked.remove(app.pid);
2907                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2908            }
2909            checkTime(startTime, "startProcess: done removing from pids map");
2910            app.setPid(0);
2911        }
2912
2913        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2914                "startProcessLocked removing on hold: " + app);
2915        mProcessesOnHold.remove(app);
2916
2917        checkTime(startTime, "startProcess: starting to update cpu stats");
2918        updateCpuStats();
2919        checkTime(startTime, "startProcess: done updating cpu stats");
2920
2921        try {
2922            int uid = app.uid;
2923
2924            int[] gids = null;
2925            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2926            if (!app.isolated) {
2927                int[] permGids = null;
2928                try {
2929                    checkTime(startTime, "startProcess: getting gids from package manager");
2930                    final PackageManager pm = mContext.getPackageManager();
2931                    permGids = pm.getPackageGids(app.info.packageName);
2932
2933                    if (Environment.isExternalStorageEmulated()) {
2934                        checkTime(startTime, "startProcess: checking external storage perm");
2935                        if (pm.checkPermission(
2936                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2937                                app.info.packageName) == PERMISSION_GRANTED) {
2938                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2939                        } else {
2940                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2941                        }
2942                    }
2943                } catch (PackageManager.NameNotFoundException e) {
2944                    Slog.w(TAG, "Unable to retrieve gids", e);
2945                }
2946
2947                /*
2948                 * Add shared application and profile GIDs so applications can share some
2949                 * resources like shared libraries and access user-wide resources
2950                 */
2951                if (permGids == null) {
2952                    gids = new int[2];
2953                } else {
2954                    gids = new int[permGids.length + 2];
2955                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2956                }
2957                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2958                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2959            }
2960            checkTime(startTime, "startProcess: building args");
2961            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2962                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2963                        && mTopComponent != null
2964                        && app.processName.equals(mTopComponent.getPackageName())) {
2965                    uid = 0;
2966                }
2967                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2968                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2969                    uid = 0;
2970                }
2971            }
2972            int debugFlags = 0;
2973            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2974                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2975                // Also turn on CheckJNI for debuggable apps. It's quite
2976                // awkward to turn on otherwise.
2977                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2978            }
2979            // Run the app in safe mode if its manifest requests so or the
2980            // system is booted in safe mode.
2981            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2982                mSafeMode == true) {
2983                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2984            }
2985            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2986                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2987            }
2988            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2989                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2990            }
2991            if ("1".equals(SystemProperties.get("debug.assert"))) {
2992                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2993            }
2994
2995            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2996            if (requiredAbi == null) {
2997                requiredAbi = Build.SUPPORTED_ABIS[0];
2998            }
2999
3000            String instructionSet = null;
3001            if (app.info.primaryCpuAbi != null) {
3002                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3003            }
3004
3005            // Start the process.  It will either succeed and return a result containing
3006            // the PID of the new process, or else throw a RuntimeException.
3007            boolean isActivityProcess = (entryPoint == null);
3008            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3009            checkTime(startTime, "startProcess: asking zygote to start proc");
3010            Process.ProcessStartResult startResult = Process.start(entryPoint,
3011                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3012                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3013                    app.info.dataDir, entryPointArgs);
3014            checkTime(startTime, "startProcess: returned from zygote!");
3015
3016            if (app.isolated) {
3017                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3018            }
3019            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3020            checkTime(startTime, "startProcess: done updating battery stats");
3021
3022            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3023                    UserHandle.getUserId(uid), startResult.pid, uid,
3024                    app.processName, hostingType,
3025                    hostingNameStr != null ? hostingNameStr : "");
3026
3027            if (app.persistent) {
3028                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3029            }
3030
3031            checkTime(startTime, "startProcess: building log message");
3032            StringBuilder buf = mStringBuilder;
3033            buf.setLength(0);
3034            buf.append("Start proc ");
3035            buf.append(app.processName);
3036            if (!isActivityProcess) {
3037                buf.append(" [");
3038                buf.append(entryPoint);
3039                buf.append("]");
3040            }
3041            buf.append(" for ");
3042            buf.append(hostingType);
3043            if (hostingNameStr != null) {
3044                buf.append(" ");
3045                buf.append(hostingNameStr);
3046            }
3047            buf.append(": pid=");
3048            buf.append(startResult.pid);
3049            buf.append(" uid=");
3050            buf.append(uid);
3051            buf.append(" gids={");
3052            if (gids != null) {
3053                for (int gi=0; gi<gids.length; gi++) {
3054                    if (gi != 0) buf.append(", ");
3055                    buf.append(gids[gi]);
3056
3057                }
3058            }
3059            buf.append("}");
3060            if (requiredAbi != null) {
3061                buf.append(" abi=");
3062                buf.append(requiredAbi);
3063            }
3064            Slog.i(TAG, buf.toString());
3065            app.setPid(startResult.pid);
3066            app.usingWrapper = startResult.usingWrapper;
3067            app.removed = false;
3068            app.killed = false;
3069            app.killedByAm = false;
3070            checkTime(startTime, "startProcess: starting to update pids map");
3071            synchronized (mPidsSelfLocked) {
3072                this.mPidsSelfLocked.put(startResult.pid, app);
3073                if (isActivityProcess) {
3074                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3075                    msg.obj = app;
3076                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3077                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3078                }
3079            }
3080            checkTime(startTime, "startProcess: done updating pids map");
3081        } catch (RuntimeException e) {
3082            // XXX do better error recovery.
3083            app.setPid(0);
3084            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3085            if (app.isolated) {
3086                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3087            }
3088            Slog.e(TAG, "Failure starting process " + app.processName, e);
3089        }
3090    }
3091
3092    void updateUsageStats(ActivityRecord component, boolean resumed) {
3093        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3094        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3095        if (resumed) {
3096            if (mUsageStatsService != null) {
3097                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3098                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3099            }
3100            synchronized (stats) {
3101                stats.noteActivityResumedLocked(component.app.uid);
3102            }
3103        } else {
3104            if (mUsageStatsService != null) {
3105                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3106                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3107            }
3108            synchronized (stats) {
3109                stats.noteActivityPausedLocked(component.app.uid);
3110            }
3111        }
3112    }
3113
3114    Intent getHomeIntent() {
3115        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3116        intent.setComponent(mTopComponent);
3117        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3118            intent.addCategory(Intent.CATEGORY_HOME);
3119        }
3120        return intent;
3121    }
3122
3123    boolean startHomeActivityLocked(int userId) {
3124        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3125                && mTopAction == null) {
3126            // We are running in factory test mode, but unable to find
3127            // the factory test app, so just sit around displaying the
3128            // error message and don't try to start anything.
3129            return false;
3130        }
3131        Intent intent = getHomeIntent();
3132        ActivityInfo aInfo =
3133            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3134        if (aInfo != null) {
3135            intent.setComponent(new ComponentName(
3136                    aInfo.applicationInfo.packageName, aInfo.name));
3137            // Don't do this if the home app is currently being
3138            // instrumented.
3139            aInfo = new ActivityInfo(aInfo);
3140            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3141            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3142                    aInfo.applicationInfo.uid, true);
3143            if (app == null || app.instrumentationClass == null) {
3144                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3145                mStackSupervisor.startHomeActivity(intent, aInfo);
3146            }
3147        }
3148
3149        return true;
3150    }
3151
3152    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3153        ActivityInfo ai = null;
3154        ComponentName comp = intent.getComponent();
3155        try {
3156            if (comp != null) {
3157                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3158            } else {
3159                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3160                        intent,
3161                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3162                            flags, userId);
3163
3164                if (info != null) {
3165                    ai = info.activityInfo;
3166                }
3167            }
3168        } catch (RemoteException e) {
3169            // ignore
3170        }
3171
3172        return ai;
3173    }
3174
3175    /**
3176     * Starts the "new version setup screen" if appropriate.
3177     */
3178    void startSetupActivityLocked() {
3179        // Only do this once per boot.
3180        if (mCheckedForSetup) {
3181            return;
3182        }
3183
3184        // We will show this screen if the current one is a different
3185        // version than the last one shown, and we are not running in
3186        // low-level factory test mode.
3187        final ContentResolver resolver = mContext.getContentResolver();
3188        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3189                Settings.Global.getInt(resolver,
3190                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3191            mCheckedForSetup = true;
3192
3193            // See if we should be showing the platform update setup UI.
3194            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3195            List<ResolveInfo> ris = mContext.getPackageManager()
3196                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3197
3198            // We don't allow third party apps to replace this.
3199            ResolveInfo ri = null;
3200            for (int i=0; ris != null && i<ris.size(); i++) {
3201                if ((ris.get(i).activityInfo.applicationInfo.flags
3202                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3203                    ri = ris.get(i);
3204                    break;
3205                }
3206            }
3207
3208            if (ri != null) {
3209                String vers = ri.activityInfo.metaData != null
3210                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3211                        : null;
3212                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3213                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3214                            Intent.METADATA_SETUP_VERSION);
3215                }
3216                String lastVers = Settings.Secure.getString(
3217                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3218                if (vers != null && !vers.equals(lastVers)) {
3219                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3220                    intent.setComponent(new ComponentName(
3221                            ri.activityInfo.packageName, ri.activityInfo.name));
3222                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3223                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3224                            null);
3225                }
3226            }
3227        }
3228    }
3229
3230    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3231        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3232    }
3233
3234    void enforceNotIsolatedCaller(String caller) {
3235        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3236            throw new SecurityException("Isolated process not allowed to call " + caller);
3237        }
3238    }
3239
3240    void enforceShellRestriction(String restriction, int userHandle) {
3241        if (Binder.getCallingUid() == Process.SHELL_UID) {
3242            if (userHandle < 0
3243                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3244                throw new SecurityException("Shell does not have permission to access user "
3245                        + userHandle);
3246            }
3247        }
3248    }
3249
3250    @Override
3251    public int getFrontActivityScreenCompatMode() {
3252        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3253        synchronized (this) {
3254            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3255        }
3256    }
3257
3258    @Override
3259    public void setFrontActivityScreenCompatMode(int mode) {
3260        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3261                "setFrontActivityScreenCompatMode");
3262        synchronized (this) {
3263            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3264        }
3265    }
3266
3267    @Override
3268    public int getPackageScreenCompatMode(String packageName) {
3269        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3270        synchronized (this) {
3271            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3272        }
3273    }
3274
3275    @Override
3276    public void setPackageScreenCompatMode(String packageName, int mode) {
3277        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3278                "setPackageScreenCompatMode");
3279        synchronized (this) {
3280            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3281        }
3282    }
3283
3284    @Override
3285    public boolean getPackageAskScreenCompat(String packageName) {
3286        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3287        synchronized (this) {
3288            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3289        }
3290    }
3291
3292    @Override
3293    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3294        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3295                "setPackageAskScreenCompat");
3296        synchronized (this) {
3297            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3298        }
3299    }
3300
3301    private void dispatchProcessesChanged() {
3302        int N;
3303        synchronized (this) {
3304            N = mPendingProcessChanges.size();
3305            if (mActiveProcessChanges.length < N) {
3306                mActiveProcessChanges = new ProcessChangeItem[N];
3307            }
3308            mPendingProcessChanges.toArray(mActiveProcessChanges);
3309            mAvailProcessChanges.addAll(mPendingProcessChanges);
3310            mPendingProcessChanges.clear();
3311            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3312        }
3313
3314        int i = mProcessObservers.beginBroadcast();
3315        while (i > 0) {
3316            i--;
3317            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3318            if (observer != null) {
3319                try {
3320                    for (int j=0; j<N; j++) {
3321                        ProcessChangeItem item = mActiveProcessChanges[j];
3322                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3323                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3324                                    + item.pid + " uid=" + item.uid + ": "
3325                                    + item.foregroundActivities);
3326                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3327                                    item.foregroundActivities);
3328                        }
3329                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3330                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3331                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3332                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3333                        }
3334                    }
3335                } catch (RemoteException e) {
3336                }
3337            }
3338        }
3339        mProcessObservers.finishBroadcast();
3340    }
3341
3342    private void dispatchProcessDied(int pid, int uid) {
3343        int i = mProcessObservers.beginBroadcast();
3344        while (i > 0) {
3345            i--;
3346            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3347            if (observer != null) {
3348                try {
3349                    observer.onProcessDied(pid, uid);
3350                } catch (RemoteException e) {
3351                }
3352            }
3353        }
3354        mProcessObservers.finishBroadcast();
3355    }
3356
3357    @Override
3358    public final int startActivity(IApplicationThread caller, String callingPackage,
3359            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3360            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3361        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3362            resultWho, requestCode, startFlags, profilerInfo, options,
3363            UserHandle.getCallingUserId());
3364    }
3365
3366    @Override
3367    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3368            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3369            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3370        enforceNotIsolatedCaller("startActivity");
3371        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3372                false, ALLOW_FULL_ONLY, "startActivity", null);
3373        // TODO: Switch to user app stacks here.
3374        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3375                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3376                profilerInfo, null, null, options, userId, null, null);
3377    }
3378
3379    @Override
3380    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3381            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3382            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3383
3384        // This is very dangerous -- it allows you to perform a start activity (including
3385        // permission grants) as any app that may launch one of your own activities.  So
3386        // we will only allow this to be done from activities that are part of the core framework,
3387        // and then only when they are running as the system.
3388        final ActivityRecord sourceRecord;
3389        final int targetUid;
3390        final String targetPackage;
3391        synchronized (this) {
3392            if (resultTo == null) {
3393                throw new SecurityException("Must be called from an activity");
3394            }
3395            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3396            if (sourceRecord == null) {
3397                throw new SecurityException("Called with bad activity token: " + resultTo);
3398            }
3399            if (!sourceRecord.info.packageName.equals("android")) {
3400                throw new SecurityException(
3401                        "Must be called from an activity that is declared in the android package");
3402            }
3403            if (sourceRecord.app == null) {
3404                throw new SecurityException("Called without a process attached to activity");
3405            }
3406            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3407                // This is still okay, as long as this activity is running under the
3408                // uid of the original calling activity.
3409                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3410                    throw new SecurityException(
3411                            "Calling activity in uid " + sourceRecord.app.uid
3412                                    + " must be system uid or original calling uid "
3413                                    + sourceRecord.launchedFromUid);
3414                }
3415            }
3416            targetUid = sourceRecord.launchedFromUid;
3417            targetPackage = sourceRecord.launchedFromPackage;
3418        }
3419
3420        if (userId == UserHandle.USER_NULL) {
3421            userId = UserHandle.getUserId(sourceRecord.app.uid);
3422        }
3423
3424        // TODO: Switch to user app stacks here.
3425        try {
3426            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3427                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3428                    null, null, options, userId, null, null);
3429            return ret;
3430        } catch (SecurityException e) {
3431            // XXX need to figure out how to propagate to original app.
3432            // A SecurityException here is generally actually a fault of the original
3433            // calling activity (such as a fairly granting permissions), so propagate it
3434            // back to them.
3435            /*
3436            StringBuilder msg = new StringBuilder();
3437            msg.append("While launching");
3438            msg.append(intent.toString());
3439            msg.append(": ");
3440            msg.append(e.getMessage());
3441            */
3442            throw e;
3443        }
3444    }
3445
3446    @Override
3447    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3448            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3449            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3450        enforceNotIsolatedCaller("startActivityAndWait");
3451        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3452                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3453        WaitResult res = new WaitResult();
3454        // TODO: Switch to user app stacks here.
3455        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3456                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3457                options, userId, null, null);
3458        return res;
3459    }
3460
3461    @Override
3462    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3463            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3464            int startFlags, Configuration config, Bundle options, int userId) {
3465        enforceNotIsolatedCaller("startActivityWithConfig");
3466        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3467                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3468        // TODO: Switch to user app stacks here.
3469        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3470                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3471                null, null, config, options, userId, null, null);
3472        return ret;
3473    }
3474
3475    @Override
3476    public int startActivityIntentSender(IApplicationThread caller,
3477            IntentSender intent, Intent fillInIntent, String resolvedType,
3478            IBinder resultTo, String resultWho, int requestCode,
3479            int flagsMask, int flagsValues, Bundle options) {
3480        enforceNotIsolatedCaller("startActivityIntentSender");
3481        // Refuse possible leaked file descriptors
3482        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3483            throw new IllegalArgumentException("File descriptors passed in Intent");
3484        }
3485
3486        IIntentSender sender = intent.getTarget();
3487        if (!(sender instanceof PendingIntentRecord)) {
3488            throw new IllegalArgumentException("Bad PendingIntent object");
3489        }
3490
3491        PendingIntentRecord pir = (PendingIntentRecord)sender;
3492
3493        synchronized (this) {
3494            // If this is coming from the currently resumed activity, it is
3495            // effectively saying that app switches are allowed at this point.
3496            final ActivityStack stack = getFocusedStack();
3497            if (stack.mResumedActivity != null &&
3498                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3499                mAppSwitchesAllowedTime = 0;
3500            }
3501        }
3502        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3503                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3504        return ret;
3505    }
3506
3507    @Override
3508    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3509            Intent intent, String resolvedType, IVoiceInteractionSession session,
3510            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3511            Bundle options, int userId) {
3512        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3513                != PackageManager.PERMISSION_GRANTED) {
3514            String msg = "Permission Denial: startVoiceActivity() from pid="
3515                    + Binder.getCallingPid()
3516                    + ", uid=" + Binder.getCallingUid()
3517                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3518            Slog.w(TAG, msg);
3519            throw new SecurityException(msg);
3520        }
3521        if (session == null || interactor == null) {
3522            throw new NullPointerException("null session or interactor");
3523        }
3524        userId = handleIncomingUser(callingPid, callingUid, userId,
3525                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3526        // TODO: Switch to user app stacks here.
3527        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3528                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3529                null, options, userId, null, null);
3530    }
3531
3532    @Override
3533    public boolean startNextMatchingActivity(IBinder callingActivity,
3534            Intent intent, Bundle options) {
3535        // Refuse possible leaked file descriptors
3536        if (intent != null && intent.hasFileDescriptors() == true) {
3537            throw new IllegalArgumentException("File descriptors passed in Intent");
3538        }
3539
3540        synchronized (this) {
3541            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3542            if (r == null) {
3543                ActivityOptions.abort(options);
3544                return false;
3545            }
3546            if (r.app == null || r.app.thread == null) {
3547                // The caller is not running...  d'oh!
3548                ActivityOptions.abort(options);
3549                return false;
3550            }
3551            intent = new Intent(intent);
3552            // The caller is not allowed to change the data.
3553            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3554            // And we are resetting to find the next component...
3555            intent.setComponent(null);
3556
3557            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3558
3559            ActivityInfo aInfo = null;
3560            try {
3561                List<ResolveInfo> resolves =
3562                    AppGlobals.getPackageManager().queryIntentActivities(
3563                            intent, r.resolvedType,
3564                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3565                            UserHandle.getCallingUserId());
3566
3567                // Look for the original activity in the list...
3568                final int N = resolves != null ? resolves.size() : 0;
3569                for (int i=0; i<N; i++) {
3570                    ResolveInfo rInfo = resolves.get(i);
3571                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3572                            && rInfo.activityInfo.name.equals(r.info.name)) {
3573                        // We found the current one...  the next matching is
3574                        // after it.
3575                        i++;
3576                        if (i<N) {
3577                            aInfo = resolves.get(i).activityInfo;
3578                        }
3579                        if (debug) {
3580                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3581                                    + "/" + r.info.name);
3582                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3583                                    + "/" + aInfo.name);
3584                        }
3585                        break;
3586                    }
3587                }
3588            } catch (RemoteException e) {
3589            }
3590
3591            if (aInfo == null) {
3592                // Nobody who is next!
3593                ActivityOptions.abort(options);
3594                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3595                return false;
3596            }
3597
3598            intent.setComponent(new ComponentName(
3599                    aInfo.applicationInfo.packageName, aInfo.name));
3600            intent.setFlags(intent.getFlags()&~(
3601                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3602                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3603                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3604                    Intent.FLAG_ACTIVITY_NEW_TASK));
3605
3606            // Okay now we need to start the new activity, replacing the
3607            // currently running activity.  This is a little tricky because
3608            // we want to start the new one as if the current one is finished,
3609            // but not finish the current one first so that there is no flicker.
3610            // And thus...
3611            final boolean wasFinishing = r.finishing;
3612            r.finishing = true;
3613
3614            // Propagate reply information over to the new activity.
3615            final ActivityRecord resultTo = r.resultTo;
3616            final String resultWho = r.resultWho;
3617            final int requestCode = r.requestCode;
3618            r.resultTo = null;
3619            if (resultTo != null) {
3620                resultTo.removeResultsLocked(r, resultWho, requestCode);
3621            }
3622
3623            final long origId = Binder.clearCallingIdentity();
3624            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3625                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3626                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3627                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3628            Binder.restoreCallingIdentity(origId);
3629
3630            r.finishing = wasFinishing;
3631            if (res != ActivityManager.START_SUCCESS) {
3632                return false;
3633            }
3634            return true;
3635        }
3636    }
3637
3638    @Override
3639    public final int startActivityFromRecents(int taskId, Bundle options) {
3640        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3641            String msg = "Permission Denial: startActivityFromRecents called without " +
3642                    START_TASKS_FROM_RECENTS;
3643            Slog.w(TAG, msg);
3644            throw new SecurityException(msg);
3645        }
3646        return startActivityFromRecentsInner(taskId, options);
3647    }
3648
3649    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3650        final TaskRecord task;
3651        final int callingUid;
3652        final String callingPackage;
3653        final Intent intent;
3654        final int userId;
3655        synchronized (this) {
3656            task = recentTaskForIdLocked(taskId);
3657            if (task == null) {
3658                throw new IllegalArgumentException("Task " + taskId + " not found.");
3659            }
3660            callingUid = task.mCallingUid;
3661            callingPackage = task.mCallingPackage;
3662            intent = task.intent;
3663            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3664            userId = task.userId;
3665        }
3666        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3667                options, userId, null, task);
3668    }
3669
3670    final int startActivityInPackage(int uid, String callingPackage,
3671            Intent intent, String resolvedType, IBinder resultTo,
3672            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3673            IActivityContainer container, TaskRecord inTask) {
3674
3675        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3676                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3677
3678        // TODO: Switch to user app stacks here.
3679        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3680                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3681                null, null, null, options, userId, container, inTask);
3682        return ret;
3683    }
3684
3685    @Override
3686    public final int startActivities(IApplicationThread caller, String callingPackage,
3687            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3688            int userId) {
3689        enforceNotIsolatedCaller("startActivities");
3690        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3691                false, ALLOW_FULL_ONLY, "startActivity", null);
3692        // TODO: Switch to user app stacks here.
3693        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3694                resolvedTypes, resultTo, options, userId);
3695        return ret;
3696    }
3697
3698    final int startActivitiesInPackage(int uid, String callingPackage,
3699            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3700            Bundle options, int userId) {
3701
3702        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3703                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3704        // TODO: Switch to user app stacks here.
3705        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3706                resultTo, options, userId);
3707        return ret;
3708    }
3709
3710    //explicitly remove thd old information in mRecentTasks when removing existing user.
3711    private void removeRecentTasksForUserLocked(int userId) {
3712        if(userId <= 0) {
3713            Slog.i(TAG, "Can't remove recent task on user " + userId);
3714            return;
3715        }
3716
3717        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3718            TaskRecord tr = mRecentTasks.get(i);
3719            if (tr.userId == userId) {
3720                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3721                        + " when finishing user" + userId);
3722                mRecentTasks.remove(i);
3723                tr.removedFromRecents(mTaskPersister);
3724            }
3725        }
3726
3727        // Remove tasks from persistent storage.
3728        mTaskPersister.wakeup(null, true);
3729    }
3730
3731    // Sort by taskId
3732    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3733        @Override
3734        public int compare(TaskRecord lhs, TaskRecord rhs) {
3735            return rhs.taskId - lhs.taskId;
3736        }
3737    };
3738
3739    // Extract the affiliates of the chain containing mRecentTasks[start].
3740    private int processNextAffiliateChain(int start) {
3741        final TaskRecord startTask = mRecentTasks.get(start);
3742        final int affiliateId = startTask.mAffiliatedTaskId;
3743
3744        // Quick identification of isolated tasks. I.e. those not launched behind.
3745        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3746                startTask.mNextAffiliate == null) {
3747            // There is still a slim chance that there are other tasks that point to this task
3748            // and that the chain is so messed up that this task no longer points to them but
3749            // the gain of this optimization outweighs the risk.
3750            startTask.inRecents = true;
3751            return start + 1;
3752        }
3753
3754        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3755        mTmpRecents.clear();
3756        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3757            final TaskRecord task = mRecentTasks.get(i);
3758            if (task.mAffiliatedTaskId == affiliateId) {
3759                mRecentTasks.remove(i);
3760                mTmpRecents.add(task);
3761            }
3762        }
3763
3764        // Sort them all by taskId. That is the order they were create in and that order will
3765        // always be correct.
3766        Collections.sort(mTmpRecents, mTaskRecordComparator);
3767
3768        // Go through and fix up the linked list.
3769        // The first one is the end of the chain and has no next.
3770        final TaskRecord first = mTmpRecents.get(0);
3771        first.inRecents = true;
3772        if (first.mNextAffiliate != null) {
3773            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3774            first.setNextAffiliate(null);
3775            mTaskPersister.wakeup(first, false);
3776        }
3777        // Everything in the middle is doubly linked from next to prev.
3778        final int tmpSize = mTmpRecents.size();
3779        for (int i = 0; i < tmpSize - 1; ++i) {
3780            final TaskRecord next = mTmpRecents.get(i);
3781            final TaskRecord prev = mTmpRecents.get(i + 1);
3782            if (next.mPrevAffiliate != prev) {
3783                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3784                        " setting prev=" + prev);
3785                next.setPrevAffiliate(prev);
3786                mTaskPersister.wakeup(next, false);
3787            }
3788            if (prev.mNextAffiliate != next) {
3789                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3790                        " setting next=" + next);
3791                prev.setNextAffiliate(next);
3792                mTaskPersister.wakeup(prev, false);
3793            }
3794            prev.inRecents = true;
3795        }
3796        // The last one is the beginning of the list and has no prev.
3797        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3798        if (last.mPrevAffiliate != null) {
3799            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3800            last.setPrevAffiliate(null);
3801            mTaskPersister.wakeup(last, false);
3802        }
3803
3804        // Insert the group back into mRecentTasks at start.
3805        mRecentTasks.addAll(start, mTmpRecents);
3806
3807        // Let the caller know where we left off.
3808        return start + tmpSize;
3809    }
3810
3811    /**
3812     * Update the recent tasks lists: make sure tasks should still be here (their
3813     * applications / activities still exist), update their availability, fixup ordering
3814     * of affiliations.
3815     */
3816    void cleanupRecentTasksLocked(int userId) {
3817        if (mRecentTasks == null) {
3818            // Happens when called from the packagemanager broadcast before boot.
3819            return;
3820        }
3821
3822        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3823        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3824        final IPackageManager pm = AppGlobals.getPackageManager();
3825        final ActivityInfo dummyAct = new ActivityInfo();
3826        final ApplicationInfo dummyApp = new ApplicationInfo();
3827
3828        int N = mRecentTasks.size();
3829
3830        int[] users = userId == UserHandle.USER_ALL
3831                ? getUsersLocked() : new int[] { userId };
3832        for (int user : users) {
3833            for (int i = 0; i < N; i++) {
3834                TaskRecord task = mRecentTasks.get(i);
3835                if (task.userId != user) {
3836                    // Only look at tasks for the user ID of interest.
3837                    continue;
3838                }
3839                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3840                    // This situation is broken, and we should just get rid of it now.
3841                    mRecentTasks.remove(i);
3842                    task.removedFromRecents(mTaskPersister);
3843                    i--;
3844                    N--;
3845                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3846                    continue;
3847                }
3848                // Check whether this activity is currently available.
3849                if (task.realActivity != null) {
3850                    ActivityInfo ai = availActCache.get(task.realActivity);
3851                    if (ai == null) {
3852                        try {
3853                            ai = pm.getActivityInfo(task.realActivity,
3854                                    PackageManager.GET_UNINSTALLED_PACKAGES
3855                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3856                        } catch (RemoteException e) {
3857                            // Will never happen.
3858                            continue;
3859                        }
3860                        if (ai == null) {
3861                            ai = dummyAct;
3862                        }
3863                        availActCache.put(task.realActivity, ai);
3864                    }
3865                    if (ai == dummyAct) {
3866                        // This could be either because the activity no longer exists, or the
3867                        // app is temporarily gone.  For the former we want to remove the recents
3868                        // entry; for the latter we want to mark it as unavailable.
3869                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3870                        if (app == null) {
3871                            try {
3872                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3873                                        PackageManager.GET_UNINSTALLED_PACKAGES
3874                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3875                            } catch (RemoteException e) {
3876                                // Will never happen.
3877                                continue;
3878                            }
3879                            if (app == null) {
3880                                app = dummyApp;
3881                            }
3882                            availAppCache.put(task.realActivity.getPackageName(), app);
3883                        }
3884                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3885                            // Doesn't exist any more!  Good-bye.
3886                            mRecentTasks.remove(i);
3887                            task.removedFromRecents(mTaskPersister);
3888                            i--;
3889                            N--;
3890                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3891                            continue;
3892                        } else {
3893                            // Otherwise just not available for now.
3894                            if (task.isAvailable) {
3895                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3896                                        + task);
3897                            }
3898                            task.isAvailable = false;
3899                        }
3900                    } else {
3901                        if (!ai.enabled || !ai.applicationInfo.enabled
3902                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3903                            if (task.isAvailable) {
3904                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3905                                        + task + " (enabled=" + ai.enabled + "/"
3906                                        + ai.applicationInfo.enabled +  " flags="
3907                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3908                            }
3909                            task.isAvailable = false;
3910                        } else {
3911                            if (!task.isAvailable) {
3912                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3913                                        + task);
3914                            }
3915                            task.isAvailable = true;
3916                        }
3917                    }
3918                }
3919            }
3920        }
3921
3922        // Verify the affiliate chain for each task.
3923        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
3924        }
3925
3926        mTmpRecents.clear();
3927        // mRecentTasks is now in sorted, affiliated order.
3928    }
3929
3930    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3931        int N = mRecentTasks.size();
3932        TaskRecord top = task;
3933        int topIndex = taskIndex;
3934        while (top.mNextAffiliate != null && topIndex > 0) {
3935            top = top.mNextAffiliate;
3936            topIndex--;
3937        }
3938        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3939                + topIndex + " from intial " + taskIndex);
3940        // Find the end of the chain, doing a sanity check along the way.
3941        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3942        int endIndex = topIndex;
3943        TaskRecord prev = top;
3944        while (endIndex < N) {
3945            TaskRecord cur = mRecentTasks.get(endIndex);
3946            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3947                    + endIndex + " " + cur);
3948            if (cur == top) {
3949                // Verify start of the chain.
3950                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3951                    Slog.wtf(TAG, "Bad chain @" + endIndex
3952                            + ": first task has next affiliate: " + prev);
3953                    sane = false;
3954                    break;
3955                }
3956            } else {
3957                // Verify middle of the chain's next points back to the one before.
3958                if (cur.mNextAffiliate != prev
3959                        || cur.mNextAffiliateTaskId != prev.taskId) {
3960                    Slog.wtf(TAG, "Bad chain @" + endIndex
3961                            + ": middle task " + cur + " @" + endIndex
3962                            + " has bad next affiliate "
3963                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3964                            + ", expected " + prev);
3965                    sane = false;
3966                    break;
3967                }
3968            }
3969            if (cur.mPrevAffiliateTaskId == -1) {
3970                // Chain ends here.
3971                if (cur.mPrevAffiliate != null) {
3972                    Slog.wtf(TAG, "Bad chain @" + endIndex
3973                            + ": last task " + cur + " has previous affiliate "
3974                            + cur.mPrevAffiliate);
3975                    sane = false;
3976                }
3977                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3978                break;
3979            } else {
3980                // Verify middle of the chain's prev points to a valid item.
3981                if (cur.mPrevAffiliate == null) {
3982                    Slog.wtf(TAG, "Bad chain @" + endIndex
3983                            + ": task " + cur + " has previous affiliate "
3984                            + cur.mPrevAffiliate + " but should be id "
3985                            + cur.mPrevAffiliate);
3986                    sane = false;
3987                    break;
3988                }
3989            }
3990            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3991                Slog.wtf(TAG, "Bad chain @" + endIndex
3992                        + ": task " + cur + " has affiliated id "
3993                        + cur.mAffiliatedTaskId + " but should be "
3994                        + task.mAffiliatedTaskId);
3995                sane = false;
3996                break;
3997            }
3998            prev = cur;
3999            endIndex++;
4000            if (endIndex >= N) {
4001                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4002                        + ": last task " + prev);
4003                sane = false;
4004                break;
4005            }
4006        }
4007        if (sane) {
4008            if (endIndex < taskIndex) {
4009                Slog.wtf(TAG, "Bad chain @" + endIndex
4010                        + ": did not extend to task " + task + " @" + taskIndex);
4011                sane = false;
4012            }
4013        }
4014        if (sane) {
4015            // All looks good, we can just move all of the affiliated tasks
4016            // to the top.
4017            for (int i=topIndex; i<=endIndex; i++) {
4018                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4019                        + " from " + i + " to " + (i-topIndex));
4020                TaskRecord cur = mRecentTasks.remove(i);
4021                mRecentTasks.add(i-topIndex, cur);
4022            }
4023            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4024                    + " to " + endIndex);
4025            return true;
4026        }
4027
4028        // Whoops, couldn't do it.
4029        return false;
4030    }
4031
4032    final void addRecentTaskLocked(TaskRecord task) {
4033        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4034                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4035
4036        int N = mRecentTasks.size();
4037        // Quick case: check if the top-most recent task is the same.
4038        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4039            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4040            return;
4041        }
4042        // Another quick case: check if this is part of a set of affiliated
4043        // tasks that are at the top.
4044        if (isAffiliated && N > 0 && task.inRecents
4045                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4046            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4047                    + " at top when adding " + task);
4048            return;
4049        }
4050        // Another quick case: never add voice sessions.
4051        if (task.voiceSession != null) {
4052            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4053            return;
4054        }
4055
4056        boolean needAffiliationFix = false;
4057
4058        // Slightly less quick case: the task is already in recents, so all we need
4059        // to do is move it.
4060        if (task.inRecents) {
4061            int taskIndex = mRecentTasks.indexOf(task);
4062            if (taskIndex >= 0) {
4063                if (!isAffiliated) {
4064                    // Simple case: this is not an affiliated task, so we just move it to the front.
4065                    mRecentTasks.remove(taskIndex);
4066                    mRecentTasks.add(0, task);
4067                    notifyTaskPersisterLocked(task, false);
4068                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4069                            + " from " + taskIndex);
4070                    return;
4071                } else {
4072                    // More complicated: need to keep all affiliated tasks together.
4073                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4074                        // All went well.
4075                        return;
4076                    }
4077
4078                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4079                    // everything and then go through our general path of adding a new task.
4080                    needAffiliationFix = true;
4081                }
4082            } else {
4083                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4084                needAffiliationFix = true;
4085            }
4086        }
4087
4088        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4089        trimRecentsForTask(task, true);
4090
4091        N = mRecentTasks.size();
4092        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4093            final TaskRecord tr = mRecentTasks.remove(N - 1);
4094            tr.removedFromRecents(mTaskPersister);
4095            N--;
4096        }
4097        task.inRecents = true;
4098        if (!isAffiliated || needAffiliationFix) {
4099            // If this is a simple non-affiliated task, or we had some failure trying to
4100            // handle it as part of an affilated task, then just place it at the top.
4101            mRecentTasks.add(0, task);
4102        } else if (isAffiliated) {
4103            // If this is a new affiliated task, then move all of the affiliated tasks
4104            // to the front and insert this new one.
4105            TaskRecord other = task.mNextAffiliate;
4106            if (other == null) {
4107                other = task.mPrevAffiliate;
4108            }
4109            if (other != null) {
4110                int otherIndex = mRecentTasks.indexOf(other);
4111                if (otherIndex >= 0) {
4112                    // Insert new task at appropriate location.
4113                    int taskIndex;
4114                    if (other == task.mNextAffiliate) {
4115                        // We found the index of our next affiliation, which is who is
4116                        // before us in the list, so add after that point.
4117                        taskIndex = otherIndex+1;
4118                    } else {
4119                        // We found the index of our previous affiliation, which is who is
4120                        // after us in the list, so add at their position.
4121                        taskIndex = otherIndex;
4122                    }
4123                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4124                            + taskIndex + ": " + task);
4125                    mRecentTasks.add(taskIndex, task);
4126
4127                    // Now move everything to the front.
4128                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4129                        // All went well.
4130                        return;
4131                    }
4132
4133                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4134                    // everything and then go through our general path of adding a new task.
4135                    needAffiliationFix = true;
4136                } else {
4137                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4138                            + other);
4139                    needAffiliationFix = true;
4140                }
4141            } else {
4142                if (DEBUG_RECENTS) Slog.d(TAG,
4143                        "addRecent: adding affiliated task without next/prev:" + task);
4144                needAffiliationFix = true;
4145            }
4146        }
4147        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4148
4149        if (needAffiliationFix) {
4150            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4151            cleanupRecentTasksLocked(task.userId);
4152        }
4153    }
4154
4155    /**
4156     * If needed, remove oldest existing entries in recents that are for the same kind
4157     * of task as the given one.
4158     */
4159    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4160        int N = mRecentTasks.size();
4161        final Intent intent = task.intent;
4162        final boolean document = intent != null && intent.isDocument();
4163
4164        int maxRecents = task.maxRecents - 1;
4165        for (int i=0; i<N; i++) {
4166            final TaskRecord tr = mRecentTasks.get(i);
4167            if (task != tr) {
4168                if (task.userId != tr.userId) {
4169                    continue;
4170                }
4171                if (i > MAX_RECENT_BITMAPS) {
4172                    tr.freeLastThumbnail();
4173                }
4174                final Intent trIntent = tr.intent;
4175                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4176                    (intent == null || !intent.filterEquals(trIntent))) {
4177                    continue;
4178                }
4179                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4180                if (document && trIsDocument) {
4181                    // These are the same document activity (not necessarily the same doc).
4182                    if (maxRecents > 0) {
4183                        --maxRecents;
4184                        continue;
4185                    }
4186                    // Hit the maximum number of documents for this task. Fall through
4187                    // and remove this document from recents.
4188                } else if (document || trIsDocument) {
4189                    // Only one of these is a document. Not the droid we're looking for.
4190                    continue;
4191                }
4192            }
4193
4194            if (!doTrim) {
4195                // If the caller is not actually asking for a trim, just tell them we reached
4196                // a point where the trim would happen.
4197                return i;
4198            }
4199
4200            // Either task and tr are the same or, their affinities match or their intents match
4201            // and neither of them is a document, or they are documents using the same activity
4202            // and their maxRecents has been reached.
4203            tr.disposeThumbnail();
4204            mRecentTasks.remove(i);
4205            if (task != tr) {
4206                tr.removedFromRecents(mTaskPersister);
4207            }
4208            i--;
4209            N--;
4210            if (task.intent == null) {
4211                // If the new recent task we are adding is not fully
4212                // specified, then replace it with the existing recent task.
4213                task = tr;
4214            }
4215            notifyTaskPersisterLocked(tr, false);
4216        }
4217
4218        return -1;
4219    }
4220
4221    @Override
4222    public void reportActivityFullyDrawn(IBinder token) {
4223        synchronized (this) {
4224            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4225            if (r == null) {
4226                return;
4227            }
4228            r.reportFullyDrawnLocked();
4229        }
4230    }
4231
4232    @Override
4233    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4234        synchronized (this) {
4235            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4236            if (r == null) {
4237                return;
4238            }
4239            final long origId = Binder.clearCallingIdentity();
4240            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4241            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4242                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4243            if (config != null) {
4244                r.frozenBeforeDestroy = true;
4245                if (!updateConfigurationLocked(config, r, false, false)) {
4246                    mStackSupervisor.resumeTopActivitiesLocked();
4247                }
4248            }
4249            Binder.restoreCallingIdentity(origId);
4250        }
4251    }
4252
4253    @Override
4254    public int getRequestedOrientation(IBinder token) {
4255        synchronized (this) {
4256            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4257            if (r == null) {
4258                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4259            }
4260            return mWindowManager.getAppOrientation(r.appToken);
4261        }
4262    }
4263
4264    /**
4265     * This is the internal entry point for handling Activity.finish().
4266     *
4267     * @param token The Binder token referencing the Activity we want to finish.
4268     * @param resultCode Result code, if any, from this Activity.
4269     * @param resultData Result data (Intent), if any, from this Activity.
4270     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4271     *            the root Activity in the task.
4272     *
4273     * @return Returns true if the activity successfully finished, or false if it is still running.
4274     */
4275    @Override
4276    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4277            boolean finishTask) {
4278        // Refuse possible leaked file descriptors
4279        if (resultData != null && resultData.hasFileDescriptors() == true) {
4280            throw new IllegalArgumentException("File descriptors passed in Intent");
4281        }
4282
4283        synchronized(this) {
4284            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4285            if (r == null) {
4286                return true;
4287            }
4288            // Keep track of the root activity of the task before we finish it
4289            TaskRecord tr = r.task;
4290            ActivityRecord rootR = tr.getRootActivity();
4291            if (rootR == null) {
4292                Slog.w(TAG, "Finishing task with all activities already finished");
4293            }
4294            // Do not allow task to finish in Lock Task mode.
4295            if (tr == mStackSupervisor.mLockTaskModeTask) {
4296                if (rootR == r) {
4297                    Slog.i(TAG, "Not finishing task in lock task mode");
4298                    mStackSupervisor.showLockTaskToast();
4299                    return false;
4300                }
4301            }
4302            if (mController != null) {
4303                // Find the first activity that is not finishing.
4304                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4305                if (next != null) {
4306                    // ask watcher if this is allowed
4307                    boolean resumeOK = true;
4308                    try {
4309                        resumeOK = mController.activityResuming(next.packageName);
4310                    } catch (RemoteException e) {
4311                        mController = null;
4312                        Watchdog.getInstance().setActivityController(null);
4313                    }
4314
4315                    if (!resumeOK) {
4316                        Slog.i(TAG, "Not finishing activity because controller resumed");
4317                        return false;
4318                    }
4319                }
4320            }
4321            final long origId = Binder.clearCallingIdentity();
4322            try {
4323                boolean res;
4324                if (finishTask && r == rootR) {
4325                    // If requested, remove the task that is associated to this activity only if it
4326                    // was the root activity in the task. The result code and data is ignored
4327                    // because we don't support returning them across task boundaries.
4328                    res = removeTaskByIdLocked(tr.taskId, false);
4329                    if (!res) {
4330                        Slog.i(TAG, "Removing task failed to finish activity");
4331                    }
4332                } else {
4333                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4334                            resultData, "app-request", true);
4335                    if (!res) {
4336                        Slog.i(TAG, "Failed to finish by app-request");
4337                    }
4338                }
4339                return res;
4340            } finally {
4341                Binder.restoreCallingIdentity(origId);
4342            }
4343        }
4344    }
4345
4346    @Override
4347    public final void finishHeavyWeightApp() {
4348        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4349                != PackageManager.PERMISSION_GRANTED) {
4350            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4351                    + Binder.getCallingPid()
4352                    + ", uid=" + Binder.getCallingUid()
4353                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4354            Slog.w(TAG, msg);
4355            throw new SecurityException(msg);
4356        }
4357
4358        synchronized(this) {
4359            if (mHeavyWeightProcess == null) {
4360                return;
4361            }
4362
4363            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4364                    mHeavyWeightProcess.activities);
4365            for (int i=0; i<activities.size(); i++) {
4366                ActivityRecord r = activities.get(i);
4367                if (!r.finishing) {
4368                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4369                            null, "finish-heavy", true);
4370                }
4371            }
4372
4373            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4374                    mHeavyWeightProcess.userId, 0));
4375            mHeavyWeightProcess = null;
4376        }
4377    }
4378
4379    @Override
4380    public void crashApplication(int uid, int initialPid, String packageName,
4381            String message) {
4382        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4383                != PackageManager.PERMISSION_GRANTED) {
4384            String msg = "Permission Denial: crashApplication() from pid="
4385                    + Binder.getCallingPid()
4386                    + ", uid=" + Binder.getCallingUid()
4387                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4388            Slog.w(TAG, msg);
4389            throw new SecurityException(msg);
4390        }
4391
4392        synchronized(this) {
4393            ProcessRecord proc = null;
4394
4395            // Figure out which process to kill.  We don't trust that initialPid
4396            // still has any relation to current pids, so must scan through the
4397            // list.
4398            synchronized (mPidsSelfLocked) {
4399                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4400                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4401                    if (p.uid != uid) {
4402                        continue;
4403                    }
4404                    if (p.pid == initialPid) {
4405                        proc = p;
4406                        break;
4407                    }
4408                    if (p.pkgList.containsKey(packageName)) {
4409                        proc = p;
4410                    }
4411                }
4412            }
4413
4414            if (proc == null) {
4415                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4416                        + " initialPid=" + initialPid
4417                        + " packageName=" + packageName);
4418                return;
4419            }
4420
4421            if (proc.thread != null) {
4422                if (proc.pid == Process.myPid()) {
4423                    Log.w(TAG, "crashApplication: trying to crash self!");
4424                    return;
4425                }
4426                long ident = Binder.clearCallingIdentity();
4427                try {
4428                    proc.thread.scheduleCrash(message);
4429                } catch (RemoteException e) {
4430                }
4431                Binder.restoreCallingIdentity(ident);
4432            }
4433        }
4434    }
4435
4436    @Override
4437    public final void finishSubActivity(IBinder token, String resultWho,
4438            int requestCode) {
4439        synchronized(this) {
4440            final long origId = Binder.clearCallingIdentity();
4441            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4442            if (r != null) {
4443                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4444            }
4445            Binder.restoreCallingIdentity(origId);
4446        }
4447    }
4448
4449    @Override
4450    public boolean finishActivityAffinity(IBinder token) {
4451        synchronized(this) {
4452            final long origId = Binder.clearCallingIdentity();
4453            try {
4454                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4455
4456                ActivityRecord rootR = r.task.getRootActivity();
4457                // Do not allow task to finish in Lock Task mode.
4458                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4459                    if (rootR == r) {
4460                        mStackSupervisor.showLockTaskToast();
4461                        return false;
4462                    }
4463                }
4464                boolean res = false;
4465                if (r != null) {
4466                    res = r.task.stack.finishActivityAffinityLocked(r);
4467                }
4468                return res;
4469            } finally {
4470                Binder.restoreCallingIdentity(origId);
4471            }
4472        }
4473    }
4474
4475    @Override
4476    public void finishVoiceTask(IVoiceInteractionSession session) {
4477        synchronized(this) {
4478            final long origId = Binder.clearCallingIdentity();
4479            try {
4480                mStackSupervisor.finishVoiceTask(session);
4481            } finally {
4482                Binder.restoreCallingIdentity(origId);
4483            }
4484        }
4485
4486    }
4487
4488    @Override
4489    public boolean releaseActivityInstance(IBinder token) {
4490        synchronized(this) {
4491            final long origId = Binder.clearCallingIdentity();
4492            try {
4493                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4494                if (r.task == null || r.task.stack == null) {
4495                    return false;
4496                }
4497                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4498            } finally {
4499                Binder.restoreCallingIdentity(origId);
4500            }
4501        }
4502    }
4503
4504    @Override
4505    public void releaseSomeActivities(IApplicationThread appInt) {
4506        synchronized(this) {
4507            final long origId = Binder.clearCallingIdentity();
4508            try {
4509                ProcessRecord app = getRecordForAppLocked(appInt);
4510                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4511            } finally {
4512                Binder.restoreCallingIdentity(origId);
4513            }
4514        }
4515    }
4516
4517    @Override
4518    public boolean willActivityBeVisible(IBinder token) {
4519        synchronized(this) {
4520            ActivityStack stack = ActivityRecord.getStackLocked(token);
4521            if (stack != null) {
4522                return stack.willActivityBeVisibleLocked(token);
4523            }
4524            return false;
4525        }
4526    }
4527
4528    @Override
4529    public void overridePendingTransition(IBinder token, String packageName,
4530            int enterAnim, int exitAnim) {
4531        synchronized(this) {
4532            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4533            if (self == null) {
4534                return;
4535            }
4536
4537            final long origId = Binder.clearCallingIdentity();
4538
4539            if (self.state == ActivityState.RESUMED
4540                    || self.state == ActivityState.PAUSING) {
4541                mWindowManager.overridePendingAppTransition(packageName,
4542                        enterAnim, exitAnim, null);
4543            }
4544
4545            Binder.restoreCallingIdentity(origId);
4546        }
4547    }
4548
4549    /**
4550     * Main function for removing an existing process from the activity manager
4551     * as a result of that process going away.  Clears out all connections
4552     * to the process.
4553     */
4554    private final void handleAppDiedLocked(ProcessRecord app,
4555            boolean restarting, boolean allowRestart) {
4556        int pid = app.pid;
4557        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4558        if (!kept && !restarting) {
4559            removeLruProcessLocked(app);
4560            if (pid > 0) {
4561                ProcessList.remove(pid);
4562            }
4563        }
4564
4565        if (mProfileProc == app) {
4566            clearProfilerLocked();
4567        }
4568
4569        // Remove this application's activities from active lists.
4570        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4571
4572        app.activities.clear();
4573
4574        if (app.instrumentationClass != null) {
4575            Slog.w(TAG, "Crash of app " + app.processName
4576                  + " running instrumentation " + app.instrumentationClass);
4577            Bundle info = new Bundle();
4578            info.putString("shortMsg", "Process crashed.");
4579            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4580        }
4581
4582        if (!restarting) {
4583            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4584                // If there was nothing to resume, and we are not already
4585                // restarting this process, but there is a visible activity that
4586                // is hosted by the process...  then make sure all visible
4587                // activities are running, taking care of restarting this
4588                // process.
4589                if (hasVisibleActivities) {
4590                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4591                }
4592            }
4593        }
4594    }
4595
4596    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4597        IBinder threadBinder = thread.asBinder();
4598        // Find the application record.
4599        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4600            ProcessRecord rec = mLruProcesses.get(i);
4601            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4602                return i;
4603            }
4604        }
4605        return -1;
4606    }
4607
4608    final ProcessRecord getRecordForAppLocked(
4609            IApplicationThread thread) {
4610        if (thread == null) {
4611            return null;
4612        }
4613
4614        int appIndex = getLRURecordIndexForAppLocked(thread);
4615        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4616    }
4617
4618    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4619        // If there are no longer any background processes running,
4620        // and the app that died was not running instrumentation,
4621        // then tell everyone we are now low on memory.
4622        boolean haveBg = false;
4623        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4624            ProcessRecord rec = mLruProcesses.get(i);
4625            if (rec.thread != null
4626                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4627                haveBg = true;
4628                break;
4629            }
4630        }
4631
4632        if (!haveBg) {
4633            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4634            if (doReport) {
4635                long now = SystemClock.uptimeMillis();
4636                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4637                    doReport = false;
4638                } else {
4639                    mLastMemUsageReportTime = now;
4640                }
4641            }
4642            final ArrayList<ProcessMemInfo> memInfos
4643                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4644            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4645            long now = SystemClock.uptimeMillis();
4646            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4647                ProcessRecord rec = mLruProcesses.get(i);
4648                if (rec == dyingProc || rec.thread == null) {
4649                    continue;
4650                }
4651                if (doReport) {
4652                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4653                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4654                }
4655                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4656                    // The low memory report is overriding any current
4657                    // state for a GC request.  Make sure to do
4658                    // heavy/important/visible/foreground processes first.
4659                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4660                        rec.lastRequestedGc = 0;
4661                    } else {
4662                        rec.lastRequestedGc = rec.lastLowMemory;
4663                    }
4664                    rec.reportLowMemory = true;
4665                    rec.lastLowMemory = now;
4666                    mProcessesToGc.remove(rec);
4667                    addProcessToGcListLocked(rec);
4668                }
4669            }
4670            if (doReport) {
4671                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4672                mHandler.sendMessage(msg);
4673            }
4674            scheduleAppGcsLocked();
4675        }
4676    }
4677
4678    final void appDiedLocked(ProcessRecord app) {
4679       appDiedLocked(app, app.pid, app.thread);
4680    }
4681
4682    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4683        // First check if this ProcessRecord is actually active for the pid.
4684        synchronized (mPidsSelfLocked) {
4685            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4686            if (curProc != app) {
4687                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4688                return;
4689            }
4690        }
4691
4692        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4693        synchronized (stats) {
4694            stats.noteProcessDiedLocked(app.info.uid, pid);
4695        }
4696
4697        Process.killProcessQuiet(pid);
4698        Process.killProcessGroup(app.info.uid, pid);
4699        app.killed = true;
4700
4701        // Clean up already done if the process has been re-started.
4702        if (app.pid == pid && app.thread != null &&
4703                app.thread.asBinder() == thread.asBinder()) {
4704            boolean doLowMem = app.instrumentationClass == null;
4705            boolean doOomAdj = doLowMem;
4706            if (!app.killedByAm) {
4707                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4708                        + ") has died");
4709                mAllowLowerMemLevel = true;
4710            } else {
4711                // Note that we always want to do oom adj to update our state with the
4712                // new number of procs.
4713                mAllowLowerMemLevel = false;
4714                doLowMem = false;
4715            }
4716            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4717            if (DEBUG_CLEANUP) Slog.v(
4718                TAG, "Dying app: " + app + ", pid: " + pid
4719                + ", thread: " + thread.asBinder());
4720            handleAppDiedLocked(app, false, true);
4721
4722            if (doOomAdj) {
4723                updateOomAdjLocked();
4724            }
4725            if (doLowMem) {
4726                doLowMemReportIfNeededLocked(app);
4727            }
4728        } else if (app.pid != pid) {
4729            // A new process has already been started.
4730            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4731                    + ") has died and restarted (pid " + app.pid + ").");
4732            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4733        } else if (DEBUG_PROCESSES) {
4734            Slog.d(TAG, "Received spurious death notification for thread "
4735                    + thread.asBinder());
4736        }
4737    }
4738
4739    /**
4740     * If a stack trace dump file is configured, dump process stack traces.
4741     * @param clearTraces causes the dump file to be erased prior to the new
4742     *    traces being written, if true; when false, the new traces will be
4743     *    appended to any existing file content.
4744     * @param firstPids of dalvik VM processes to dump stack traces for first
4745     * @param lastPids of dalvik VM processes to dump stack traces for last
4746     * @param nativeProcs optional list of native process names to dump stack crawls
4747     * @return file containing stack traces, or null if no dump file is configured
4748     */
4749    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4750            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4751        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4752        if (tracesPath == null || tracesPath.length() == 0) {
4753            return null;
4754        }
4755
4756        File tracesFile = new File(tracesPath);
4757        try {
4758            File tracesDir = tracesFile.getParentFile();
4759            if (!tracesDir.exists()) {
4760                tracesDir.mkdirs();
4761                if (!SELinux.restorecon(tracesDir)) {
4762                    return null;
4763                }
4764            }
4765            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4766
4767            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4768            tracesFile.createNewFile();
4769            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4770        } catch (IOException e) {
4771            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4772            return null;
4773        }
4774
4775        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4776        return tracesFile;
4777    }
4778
4779    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4780            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4781        // Use a FileObserver to detect when traces finish writing.
4782        // The order of traces is considered important to maintain for legibility.
4783        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4784            @Override
4785            public synchronized void onEvent(int event, String path) { notify(); }
4786        };
4787
4788        try {
4789            observer.startWatching();
4790
4791            // First collect all of the stacks of the most important pids.
4792            if (firstPids != null) {
4793                try {
4794                    int num = firstPids.size();
4795                    for (int i = 0; i < num; i++) {
4796                        synchronized (observer) {
4797                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4798                            observer.wait(200);  // Wait for write-close, give up after 200msec
4799                        }
4800                    }
4801                } catch (InterruptedException e) {
4802                    Slog.wtf(TAG, e);
4803                }
4804            }
4805
4806            // Next collect the stacks of the native pids
4807            if (nativeProcs != null) {
4808                int[] pids = Process.getPidsForCommands(nativeProcs);
4809                if (pids != null) {
4810                    for (int pid : pids) {
4811                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4812                    }
4813                }
4814            }
4815
4816            // Lastly, measure CPU usage.
4817            if (processCpuTracker != null) {
4818                processCpuTracker.init();
4819                System.gc();
4820                processCpuTracker.update();
4821                try {
4822                    synchronized (processCpuTracker) {
4823                        processCpuTracker.wait(500); // measure over 1/2 second.
4824                    }
4825                } catch (InterruptedException e) {
4826                }
4827                processCpuTracker.update();
4828
4829                // We'll take the stack crawls of just the top apps using CPU.
4830                final int N = processCpuTracker.countWorkingStats();
4831                int numProcs = 0;
4832                for (int i=0; i<N && numProcs<5; i++) {
4833                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4834                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4835                        numProcs++;
4836                        try {
4837                            synchronized (observer) {
4838                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4839                                observer.wait(200);  // Wait for write-close, give up after 200msec
4840                            }
4841                        } catch (InterruptedException e) {
4842                            Slog.wtf(TAG, e);
4843                        }
4844
4845                    }
4846                }
4847            }
4848        } finally {
4849            observer.stopWatching();
4850        }
4851    }
4852
4853    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4854        if (true || IS_USER_BUILD) {
4855            return;
4856        }
4857        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4858        if (tracesPath == null || tracesPath.length() == 0) {
4859            return;
4860        }
4861
4862        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4863        StrictMode.allowThreadDiskWrites();
4864        try {
4865            final File tracesFile = new File(tracesPath);
4866            final File tracesDir = tracesFile.getParentFile();
4867            final File tracesTmp = new File(tracesDir, "__tmp__");
4868            try {
4869                if (!tracesDir.exists()) {
4870                    tracesDir.mkdirs();
4871                    if (!SELinux.restorecon(tracesDir.getPath())) {
4872                        return;
4873                    }
4874                }
4875                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4876
4877                if (tracesFile.exists()) {
4878                    tracesTmp.delete();
4879                    tracesFile.renameTo(tracesTmp);
4880                }
4881                StringBuilder sb = new StringBuilder();
4882                Time tobj = new Time();
4883                tobj.set(System.currentTimeMillis());
4884                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4885                sb.append(": ");
4886                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4887                sb.append(" since ");
4888                sb.append(msg);
4889                FileOutputStream fos = new FileOutputStream(tracesFile);
4890                fos.write(sb.toString().getBytes());
4891                if (app == null) {
4892                    fos.write("\n*** No application process!".getBytes());
4893                }
4894                fos.close();
4895                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4896            } catch (IOException e) {
4897                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4898                return;
4899            }
4900
4901            if (app != null) {
4902                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4903                firstPids.add(app.pid);
4904                dumpStackTraces(tracesPath, firstPids, null, null, null);
4905            }
4906
4907            File lastTracesFile = null;
4908            File curTracesFile = null;
4909            for (int i=9; i>=0; i--) {
4910                String name = String.format(Locale.US, "slow%02d.txt", i);
4911                curTracesFile = new File(tracesDir, name);
4912                if (curTracesFile.exists()) {
4913                    if (lastTracesFile != null) {
4914                        curTracesFile.renameTo(lastTracesFile);
4915                    } else {
4916                        curTracesFile.delete();
4917                    }
4918                }
4919                lastTracesFile = curTracesFile;
4920            }
4921            tracesFile.renameTo(curTracesFile);
4922            if (tracesTmp.exists()) {
4923                tracesTmp.renameTo(tracesFile);
4924            }
4925        } finally {
4926            StrictMode.setThreadPolicy(oldPolicy);
4927        }
4928    }
4929
4930    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4931            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4932        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4933        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4934
4935        if (mController != null) {
4936            try {
4937                // 0 == continue, -1 = kill process immediately
4938                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4939                if (res < 0 && app.pid != MY_PID) {
4940                    app.kill("anr", true);
4941                }
4942            } catch (RemoteException e) {
4943                mController = null;
4944                Watchdog.getInstance().setActivityController(null);
4945            }
4946        }
4947
4948        long anrTime = SystemClock.uptimeMillis();
4949        if (MONITOR_CPU_USAGE) {
4950            updateCpuStatsNow();
4951        }
4952
4953        synchronized (this) {
4954            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4955            if (mShuttingDown) {
4956                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4957                return;
4958            } else if (app.notResponding) {
4959                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4960                return;
4961            } else if (app.crashing) {
4962                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4963                return;
4964            }
4965
4966            // In case we come through here for the same app before completing
4967            // this one, mark as anring now so we will bail out.
4968            app.notResponding = true;
4969
4970            // Log the ANR to the event log.
4971            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4972                    app.processName, app.info.flags, annotation);
4973
4974            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4975            firstPids.add(app.pid);
4976
4977            int parentPid = app.pid;
4978            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4979            if (parentPid != app.pid) firstPids.add(parentPid);
4980
4981            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4982
4983            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4984                ProcessRecord r = mLruProcesses.get(i);
4985                if (r != null && r.thread != null) {
4986                    int pid = r.pid;
4987                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4988                        if (r.persistent) {
4989                            firstPids.add(pid);
4990                        } else {
4991                            lastPids.put(pid, Boolean.TRUE);
4992                        }
4993                    }
4994                }
4995            }
4996        }
4997
4998        // Log the ANR to the main log.
4999        StringBuilder info = new StringBuilder();
5000        info.setLength(0);
5001        info.append("ANR in ").append(app.processName);
5002        if (activity != null && activity.shortComponentName != null) {
5003            info.append(" (").append(activity.shortComponentName).append(")");
5004        }
5005        info.append("\n");
5006        info.append("PID: ").append(app.pid).append("\n");
5007        if (annotation != null) {
5008            info.append("Reason: ").append(annotation).append("\n");
5009        }
5010        if (parent != null && parent != activity) {
5011            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5012        }
5013
5014        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5015
5016        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5017                NATIVE_STACKS_OF_INTEREST);
5018
5019        String cpuInfo = null;
5020        if (MONITOR_CPU_USAGE) {
5021            updateCpuStatsNow();
5022            synchronized (mProcessCpuTracker) {
5023                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5024            }
5025            info.append(processCpuTracker.printCurrentLoad());
5026            info.append(cpuInfo);
5027        }
5028
5029        info.append(processCpuTracker.printCurrentState(anrTime));
5030
5031        Slog.e(TAG, info.toString());
5032        if (tracesFile == null) {
5033            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5034            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5035        }
5036
5037        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5038                cpuInfo, tracesFile, null);
5039
5040        if (mController != null) {
5041            try {
5042                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5043                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5044                if (res != 0) {
5045                    if (res < 0 && app.pid != MY_PID) {
5046                        app.kill("anr", true);
5047                    } else {
5048                        synchronized (this) {
5049                            mServices.scheduleServiceTimeoutLocked(app);
5050                        }
5051                    }
5052                    return;
5053                }
5054            } catch (RemoteException e) {
5055                mController = null;
5056                Watchdog.getInstance().setActivityController(null);
5057            }
5058        }
5059
5060        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5061        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5062                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5063
5064        synchronized (this) {
5065            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5066                app.kill("bg anr", true);
5067                return;
5068            }
5069
5070            // Set the app's notResponding state, and look up the errorReportReceiver
5071            makeAppNotRespondingLocked(app,
5072                    activity != null ? activity.shortComponentName : null,
5073                    annotation != null ? "ANR " + annotation : "ANR",
5074                    info.toString());
5075
5076            // Bring up the infamous App Not Responding dialog
5077            Message msg = Message.obtain();
5078            HashMap<String, Object> map = new HashMap<String, Object>();
5079            msg.what = SHOW_NOT_RESPONDING_MSG;
5080            msg.obj = map;
5081            msg.arg1 = aboveSystem ? 1 : 0;
5082            map.put("app", app);
5083            if (activity != null) {
5084                map.put("activity", activity);
5085            }
5086
5087            mHandler.sendMessage(msg);
5088        }
5089    }
5090
5091    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5092        if (!mLaunchWarningShown) {
5093            mLaunchWarningShown = true;
5094            mHandler.post(new Runnable() {
5095                @Override
5096                public void run() {
5097                    synchronized (ActivityManagerService.this) {
5098                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5099                        d.show();
5100                        mHandler.postDelayed(new Runnable() {
5101                            @Override
5102                            public void run() {
5103                                synchronized (ActivityManagerService.this) {
5104                                    d.dismiss();
5105                                    mLaunchWarningShown = false;
5106                                }
5107                            }
5108                        }, 4000);
5109                    }
5110                }
5111            });
5112        }
5113    }
5114
5115    @Override
5116    public boolean clearApplicationUserData(final String packageName,
5117            final IPackageDataObserver observer, int userId) {
5118        enforceNotIsolatedCaller("clearApplicationUserData");
5119        int uid = Binder.getCallingUid();
5120        int pid = Binder.getCallingPid();
5121        userId = handleIncomingUser(pid, uid,
5122                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5123        long callingId = Binder.clearCallingIdentity();
5124        try {
5125            IPackageManager pm = AppGlobals.getPackageManager();
5126            int pkgUid = -1;
5127            synchronized(this) {
5128                try {
5129                    pkgUid = pm.getPackageUid(packageName, userId);
5130                } catch (RemoteException e) {
5131                }
5132                if (pkgUid == -1) {
5133                    Slog.w(TAG, "Invalid packageName: " + packageName);
5134                    if (observer != null) {
5135                        try {
5136                            observer.onRemoveCompleted(packageName, false);
5137                        } catch (RemoteException e) {
5138                            Slog.i(TAG, "Observer no longer exists.");
5139                        }
5140                    }
5141                    return false;
5142                }
5143                if (uid == pkgUid || checkComponentPermission(
5144                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5145                        pid, uid, -1, true)
5146                        == PackageManager.PERMISSION_GRANTED) {
5147                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5148                } else {
5149                    throw new SecurityException("PID " + pid + " does not have permission "
5150                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5151                                    + " of package " + packageName);
5152                }
5153
5154                // Remove all tasks match the cleared application package and user
5155                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5156                    final TaskRecord tr = mRecentTasks.get(i);
5157                    final String taskPackageName =
5158                            tr.getBaseIntent().getComponent().getPackageName();
5159                    if (tr.userId != userId) continue;
5160                    if (!taskPackageName.equals(packageName)) continue;
5161                    removeTaskByIdLocked(tr.taskId, false);
5162                }
5163            }
5164
5165            try {
5166                // Clear application user data
5167                pm.clearApplicationUserData(packageName, observer, userId);
5168
5169                synchronized(this) {
5170                    // Remove all permissions granted from/to this package
5171                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5172                }
5173
5174                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5175                        Uri.fromParts("package", packageName, null));
5176                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5177                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5178                        null, null, 0, null, null, null, false, false, userId);
5179            } catch (RemoteException e) {
5180            }
5181        } finally {
5182            Binder.restoreCallingIdentity(callingId);
5183        }
5184        return true;
5185    }
5186
5187    @Override
5188    public void killBackgroundProcesses(final String packageName, int userId) {
5189        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5190                != PackageManager.PERMISSION_GRANTED &&
5191                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5192                        != PackageManager.PERMISSION_GRANTED) {
5193            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5194                    + Binder.getCallingPid()
5195                    + ", uid=" + Binder.getCallingUid()
5196                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5197            Slog.w(TAG, msg);
5198            throw new SecurityException(msg);
5199        }
5200
5201        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5202                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5203        long callingId = Binder.clearCallingIdentity();
5204        try {
5205            IPackageManager pm = AppGlobals.getPackageManager();
5206            synchronized(this) {
5207                int appId = -1;
5208                try {
5209                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5210                } catch (RemoteException e) {
5211                }
5212                if (appId == -1) {
5213                    Slog.w(TAG, "Invalid packageName: " + packageName);
5214                    return;
5215                }
5216                killPackageProcessesLocked(packageName, appId, userId,
5217                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5218            }
5219        } finally {
5220            Binder.restoreCallingIdentity(callingId);
5221        }
5222    }
5223
5224    @Override
5225    public void killAllBackgroundProcesses() {
5226        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5227                != PackageManager.PERMISSION_GRANTED) {
5228            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5229                    + Binder.getCallingPid()
5230                    + ", uid=" + Binder.getCallingUid()
5231                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5232            Slog.w(TAG, msg);
5233            throw new SecurityException(msg);
5234        }
5235
5236        long callingId = Binder.clearCallingIdentity();
5237        try {
5238            synchronized(this) {
5239                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5240                final int NP = mProcessNames.getMap().size();
5241                for (int ip=0; ip<NP; ip++) {
5242                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5243                    final int NA = apps.size();
5244                    for (int ia=0; ia<NA; ia++) {
5245                        ProcessRecord app = apps.valueAt(ia);
5246                        if (app.persistent) {
5247                            // we don't kill persistent processes
5248                            continue;
5249                        }
5250                        if (app.removed) {
5251                            procs.add(app);
5252                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5253                            app.removed = true;
5254                            procs.add(app);
5255                        }
5256                    }
5257                }
5258
5259                int N = procs.size();
5260                for (int i=0; i<N; i++) {
5261                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5262                }
5263                mAllowLowerMemLevel = true;
5264                updateOomAdjLocked();
5265                doLowMemReportIfNeededLocked(null);
5266            }
5267        } finally {
5268            Binder.restoreCallingIdentity(callingId);
5269        }
5270    }
5271
5272    @Override
5273    public void forceStopPackage(final String packageName, int userId) {
5274        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5275                != PackageManager.PERMISSION_GRANTED) {
5276            String msg = "Permission Denial: forceStopPackage() from pid="
5277                    + Binder.getCallingPid()
5278                    + ", uid=" + Binder.getCallingUid()
5279                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5280            Slog.w(TAG, msg);
5281            throw new SecurityException(msg);
5282        }
5283        final int callingPid = Binder.getCallingPid();
5284        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5285                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5286        long callingId = Binder.clearCallingIdentity();
5287        try {
5288            IPackageManager pm = AppGlobals.getPackageManager();
5289            synchronized(this) {
5290                int[] users = userId == UserHandle.USER_ALL
5291                        ? getUsersLocked() : new int[] { userId };
5292                for (int user : users) {
5293                    int pkgUid = -1;
5294                    try {
5295                        pkgUid = pm.getPackageUid(packageName, user);
5296                    } catch (RemoteException e) {
5297                    }
5298                    if (pkgUid == -1) {
5299                        Slog.w(TAG, "Invalid packageName: " + packageName);
5300                        continue;
5301                    }
5302                    try {
5303                        pm.setPackageStoppedState(packageName, true, user);
5304                    } catch (RemoteException e) {
5305                    } catch (IllegalArgumentException e) {
5306                        Slog.w(TAG, "Failed trying to unstop package "
5307                                + packageName + ": " + e);
5308                    }
5309                    if (isUserRunningLocked(user, false)) {
5310                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5311                    }
5312                }
5313            }
5314        } finally {
5315            Binder.restoreCallingIdentity(callingId);
5316        }
5317    }
5318
5319    @Override
5320    public void addPackageDependency(String packageName) {
5321        synchronized (this) {
5322            int callingPid = Binder.getCallingPid();
5323            if (callingPid == Process.myPid()) {
5324                //  Yeah, um, no.
5325                Slog.w(TAG, "Can't addPackageDependency on system process");
5326                return;
5327            }
5328            ProcessRecord proc;
5329            synchronized (mPidsSelfLocked) {
5330                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5331            }
5332            if (proc != null) {
5333                if (proc.pkgDeps == null) {
5334                    proc.pkgDeps = new ArraySet<String>(1);
5335                }
5336                proc.pkgDeps.add(packageName);
5337            }
5338        }
5339    }
5340
5341    /*
5342     * The pkg name and app id have to be specified.
5343     */
5344    @Override
5345    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5346        if (pkg == null) {
5347            return;
5348        }
5349        // Make sure the uid is valid.
5350        if (appid < 0) {
5351            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5352            return;
5353        }
5354        int callerUid = Binder.getCallingUid();
5355        // Only the system server can kill an application
5356        if (callerUid == Process.SYSTEM_UID) {
5357            // Post an aysnc message to kill the application
5358            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5359            msg.arg1 = appid;
5360            msg.arg2 = 0;
5361            Bundle bundle = new Bundle();
5362            bundle.putString("pkg", pkg);
5363            bundle.putString("reason", reason);
5364            msg.obj = bundle;
5365            mHandler.sendMessage(msg);
5366        } else {
5367            throw new SecurityException(callerUid + " cannot kill pkg: " +
5368                    pkg);
5369        }
5370    }
5371
5372    @Override
5373    public void closeSystemDialogs(String reason) {
5374        enforceNotIsolatedCaller("closeSystemDialogs");
5375
5376        final int pid = Binder.getCallingPid();
5377        final int uid = Binder.getCallingUid();
5378        final long origId = Binder.clearCallingIdentity();
5379        try {
5380            synchronized (this) {
5381                // Only allow this from foreground processes, so that background
5382                // applications can't abuse it to prevent system UI from being shown.
5383                if (uid >= Process.FIRST_APPLICATION_UID) {
5384                    ProcessRecord proc;
5385                    synchronized (mPidsSelfLocked) {
5386                        proc = mPidsSelfLocked.get(pid);
5387                    }
5388                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5389                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5390                                + " from background process " + proc);
5391                        return;
5392                    }
5393                }
5394                closeSystemDialogsLocked(reason);
5395            }
5396        } finally {
5397            Binder.restoreCallingIdentity(origId);
5398        }
5399    }
5400
5401    void closeSystemDialogsLocked(String reason) {
5402        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5403        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5404                | Intent.FLAG_RECEIVER_FOREGROUND);
5405        if (reason != null) {
5406            intent.putExtra("reason", reason);
5407        }
5408        mWindowManager.closeSystemDialogs(reason);
5409
5410        mStackSupervisor.closeSystemDialogsLocked();
5411
5412        broadcastIntentLocked(null, null, intent, null,
5413                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5414                Process.SYSTEM_UID, UserHandle.USER_ALL);
5415    }
5416
5417    @Override
5418    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5419        enforceNotIsolatedCaller("getProcessMemoryInfo");
5420        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5421        for (int i=pids.length-1; i>=0; i--) {
5422            ProcessRecord proc;
5423            int oomAdj;
5424            synchronized (this) {
5425                synchronized (mPidsSelfLocked) {
5426                    proc = mPidsSelfLocked.get(pids[i]);
5427                    oomAdj = proc != null ? proc.setAdj : 0;
5428                }
5429            }
5430            infos[i] = new Debug.MemoryInfo();
5431            Debug.getMemoryInfo(pids[i], infos[i]);
5432            if (proc != null) {
5433                synchronized (this) {
5434                    if (proc.thread != null && proc.setAdj == oomAdj) {
5435                        // Record this for posterity if the process has been stable.
5436                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5437                                infos[i].getTotalUss(), false, proc.pkgList);
5438                    }
5439                }
5440            }
5441        }
5442        return infos;
5443    }
5444
5445    @Override
5446    public long[] getProcessPss(int[] pids) {
5447        enforceNotIsolatedCaller("getProcessPss");
5448        long[] pss = new long[pids.length];
5449        for (int i=pids.length-1; i>=0; i--) {
5450            ProcessRecord proc;
5451            int oomAdj;
5452            synchronized (this) {
5453                synchronized (mPidsSelfLocked) {
5454                    proc = mPidsSelfLocked.get(pids[i]);
5455                    oomAdj = proc != null ? proc.setAdj : 0;
5456                }
5457            }
5458            long[] tmpUss = new long[1];
5459            pss[i] = Debug.getPss(pids[i], tmpUss);
5460            if (proc != null) {
5461                synchronized (this) {
5462                    if (proc.thread != null && proc.setAdj == oomAdj) {
5463                        // Record this for posterity if the process has been stable.
5464                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5465                    }
5466                }
5467            }
5468        }
5469        return pss;
5470    }
5471
5472    @Override
5473    public void killApplicationProcess(String processName, int uid) {
5474        if (processName == null) {
5475            return;
5476        }
5477
5478        int callerUid = Binder.getCallingUid();
5479        // Only the system server can kill an application
5480        if (callerUid == Process.SYSTEM_UID) {
5481            synchronized (this) {
5482                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5483                if (app != null && app.thread != null) {
5484                    try {
5485                        app.thread.scheduleSuicide();
5486                    } catch (RemoteException e) {
5487                        // If the other end already died, then our work here is done.
5488                    }
5489                } else {
5490                    Slog.w(TAG, "Process/uid not found attempting kill of "
5491                            + processName + " / " + uid);
5492                }
5493            }
5494        } else {
5495            throw new SecurityException(callerUid + " cannot kill app process: " +
5496                    processName);
5497        }
5498    }
5499
5500    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5501        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5502                false, true, false, false, UserHandle.getUserId(uid), reason);
5503        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5504                Uri.fromParts("package", packageName, null));
5505        if (!mProcessesReady) {
5506            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5507                    | Intent.FLAG_RECEIVER_FOREGROUND);
5508        }
5509        intent.putExtra(Intent.EXTRA_UID, uid);
5510        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5511        broadcastIntentLocked(null, null, intent,
5512                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5513                false, false,
5514                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5515    }
5516
5517    private void forceStopUserLocked(int userId, String reason) {
5518        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5519        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5520        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5521                | Intent.FLAG_RECEIVER_FOREGROUND);
5522        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5523        broadcastIntentLocked(null, null, intent,
5524                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5525                false, false,
5526                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5527    }
5528
5529    private final boolean killPackageProcessesLocked(String packageName, int appId,
5530            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5531            boolean doit, boolean evenPersistent, String reason) {
5532        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5533
5534        // Remove all processes this package may have touched: all with the
5535        // same UID (except for the system or root user), and all whose name
5536        // matches the package name.
5537        final int NP = mProcessNames.getMap().size();
5538        for (int ip=0; ip<NP; ip++) {
5539            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5540            final int NA = apps.size();
5541            for (int ia=0; ia<NA; ia++) {
5542                ProcessRecord app = apps.valueAt(ia);
5543                if (app.persistent && !evenPersistent) {
5544                    // we don't kill persistent processes
5545                    continue;
5546                }
5547                if (app.removed) {
5548                    if (doit) {
5549                        procs.add(app);
5550                    }
5551                    continue;
5552                }
5553
5554                // Skip process if it doesn't meet our oom adj requirement.
5555                if (app.setAdj < minOomAdj) {
5556                    continue;
5557                }
5558
5559                // If no package is specified, we call all processes under the
5560                // give user id.
5561                if (packageName == null) {
5562                    if (app.userId != userId) {
5563                        continue;
5564                    }
5565                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5566                        continue;
5567                    }
5568                // Package has been specified, we want to hit all processes
5569                // that match it.  We need to qualify this by the processes
5570                // that are running under the specified app and user ID.
5571                } else {
5572                    final boolean isDep = app.pkgDeps != null
5573                            && app.pkgDeps.contains(packageName);
5574                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5575                        continue;
5576                    }
5577                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5578                        continue;
5579                    }
5580                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5581                        continue;
5582                    }
5583                }
5584
5585                // Process has passed all conditions, kill it!
5586                if (!doit) {
5587                    return true;
5588                }
5589                app.removed = true;
5590                procs.add(app);
5591            }
5592        }
5593
5594        int N = procs.size();
5595        for (int i=0; i<N; i++) {
5596            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5597        }
5598        updateOomAdjLocked();
5599        return N > 0;
5600    }
5601
5602    private final boolean forceStopPackageLocked(String name, int appId,
5603            boolean callerWillRestart, boolean purgeCache, boolean doit,
5604            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5605        int i;
5606        int N;
5607
5608        if (userId == UserHandle.USER_ALL && name == null) {
5609            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5610        }
5611
5612        if (appId < 0 && name != null) {
5613            try {
5614                appId = UserHandle.getAppId(
5615                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5616            } catch (RemoteException e) {
5617            }
5618        }
5619
5620        if (doit) {
5621            if (name != null) {
5622                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5623                        + " user=" + userId + ": " + reason);
5624            } else {
5625                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5626            }
5627
5628            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5629            for (int ip=pmap.size()-1; ip>=0; ip--) {
5630                SparseArray<Long> ba = pmap.valueAt(ip);
5631                for (i=ba.size()-1; i>=0; i--) {
5632                    boolean remove = false;
5633                    final int entUid = ba.keyAt(i);
5634                    if (name != null) {
5635                        if (userId == UserHandle.USER_ALL) {
5636                            if (UserHandle.getAppId(entUid) == appId) {
5637                                remove = true;
5638                            }
5639                        } else {
5640                            if (entUid == UserHandle.getUid(userId, appId)) {
5641                                remove = true;
5642                            }
5643                        }
5644                    } else if (UserHandle.getUserId(entUid) == userId) {
5645                        remove = true;
5646                    }
5647                    if (remove) {
5648                        ba.removeAt(i);
5649                    }
5650                }
5651                if (ba.size() == 0) {
5652                    pmap.removeAt(ip);
5653                }
5654            }
5655        }
5656
5657        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5658                -100, callerWillRestart, true, doit, evenPersistent,
5659                name == null ? ("stop user " + userId) : ("stop " + name));
5660
5661        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5662            if (!doit) {
5663                return true;
5664            }
5665            didSomething = true;
5666        }
5667
5668        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5669            if (!doit) {
5670                return true;
5671            }
5672            didSomething = true;
5673        }
5674
5675        if (name == null) {
5676            // Remove all sticky broadcasts from this user.
5677            mStickyBroadcasts.remove(userId);
5678        }
5679
5680        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5681        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5682                userId, providers)) {
5683            if (!doit) {
5684                return true;
5685            }
5686            didSomething = true;
5687        }
5688        N = providers.size();
5689        for (i=0; i<N; i++) {
5690            removeDyingProviderLocked(null, providers.get(i), true);
5691        }
5692
5693        // Remove transient permissions granted from/to this package/user
5694        removeUriPermissionsForPackageLocked(name, userId, false);
5695
5696        if (name == null || uninstalling) {
5697            // Remove pending intents.  For now we only do this when force
5698            // stopping users, because we have some problems when doing this
5699            // for packages -- app widgets are not currently cleaned up for
5700            // such packages, so they can be left with bad pending intents.
5701            if (mIntentSenderRecords.size() > 0) {
5702                Iterator<WeakReference<PendingIntentRecord>> it
5703                        = mIntentSenderRecords.values().iterator();
5704                while (it.hasNext()) {
5705                    WeakReference<PendingIntentRecord> wpir = it.next();
5706                    if (wpir == null) {
5707                        it.remove();
5708                        continue;
5709                    }
5710                    PendingIntentRecord pir = wpir.get();
5711                    if (pir == null) {
5712                        it.remove();
5713                        continue;
5714                    }
5715                    if (name == null) {
5716                        // Stopping user, remove all objects for the user.
5717                        if (pir.key.userId != userId) {
5718                            // Not the same user, skip it.
5719                            continue;
5720                        }
5721                    } else {
5722                        if (UserHandle.getAppId(pir.uid) != appId) {
5723                            // Different app id, skip it.
5724                            continue;
5725                        }
5726                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5727                            // Different user, skip it.
5728                            continue;
5729                        }
5730                        if (!pir.key.packageName.equals(name)) {
5731                            // Different package, skip it.
5732                            continue;
5733                        }
5734                    }
5735                    if (!doit) {
5736                        return true;
5737                    }
5738                    didSomething = true;
5739                    it.remove();
5740                    pir.canceled = true;
5741                    if (pir.key.activity != null) {
5742                        pir.key.activity.pendingResults.remove(pir.ref);
5743                    }
5744                }
5745            }
5746        }
5747
5748        if (doit) {
5749            if (purgeCache && name != null) {
5750                AttributeCache ac = AttributeCache.instance();
5751                if (ac != null) {
5752                    ac.removePackage(name);
5753                }
5754            }
5755            if (mBooted) {
5756                mStackSupervisor.resumeTopActivitiesLocked();
5757                mStackSupervisor.scheduleIdleLocked();
5758            }
5759        }
5760
5761        return didSomething;
5762    }
5763
5764    private final boolean removeProcessLocked(ProcessRecord app,
5765            boolean callerWillRestart, boolean allowRestart, String reason) {
5766        final String name = app.processName;
5767        final int uid = app.uid;
5768        if (DEBUG_PROCESSES) Slog.d(
5769            TAG, "Force removing proc " + app.toShortString() + " (" + name
5770            + "/" + uid + ")");
5771
5772        mProcessNames.remove(name, uid);
5773        mIsolatedProcesses.remove(app.uid);
5774        if (mHeavyWeightProcess == app) {
5775            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5776                    mHeavyWeightProcess.userId, 0));
5777            mHeavyWeightProcess = null;
5778        }
5779        boolean needRestart = false;
5780        if (app.pid > 0 && app.pid != MY_PID) {
5781            int pid = app.pid;
5782            synchronized (mPidsSelfLocked) {
5783                mPidsSelfLocked.remove(pid);
5784                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5785            }
5786            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5787            if (app.isolated) {
5788                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5789            }
5790            app.kill(reason, true);
5791            handleAppDiedLocked(app, true, allowRestart);
5792            removeLruProcessLocked(app);
5793
5794            if (app.persistent && !app.isolated) {
5795                if (!callerWillRestart) {
5796                    addAppLocked(app.info, false, null /* ABI override */);
5797                } else {
5798                    needRestart = true;
5799                }
5800            }
5801        } else {
5802            mRemovedProcesses.add(app);
5803        }
5804
5805        return needRestart;
5806    }
5807
5808    private final void processStartTimedOutLocked(ProcessRecord app) {
5809        final int pid = app.pid;
5810        boolean gone = false;
5811        synchronized (mPidsSelfLocked) {
5812            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5813            if (knownApp != null && knownApp.thread == null) {
5814                mPidsSelfLocked.remove(pid);
5815                gone = true;
5816            }
5817        }
5818
5819        if (gone) {
5820            Slog.w(TAG, "Process " + app + " failed to attach");
5821            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5822                    pid, app.uid, app.processName);
5823            mProcessNames.remove(app.processName, app.uid);
5824            mIsolatedProcesses.remove(app.uid);
5825            if (mHeavyWeightProcess == app) {
5826                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5827                        mHeavyWeightProcess.userId, 0));
5828                mHeavyWeightProcess = null;
5829            }
5830            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5831            if (app.isolated) {
5832                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5833            }
5834            // Take care of any launching providers waiting for this process.
5835            checkAppInLaunchingProvidersLocked(app, true);
5836            // Take care of any services that are waiting for the process.
5837            mServices.processStartTimedOutLocked(app);
5838            app.kill("start timeout", true);
5839            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5840                Slog.w(TAG, "Unattached app died before backup, skipping");
5841                try {
5842                    IBackupManager bm = IBackupManager.Stub.asInterface(
5843                            ServiceManager.getService(Context.BACKUP_SERVICE));
5844                    bm.agentDisconnected(app.info.packageName);
5845                } catch (RemoteException e) {
5846                    // Can't happen; the backup manager is local
5847                }
5848            }
5849            if (isPendingBroadcastProcessLocked(pid)) {
5850                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5851                skipPendingBroadcastLocked(pid);
5852            }
5853        } else {
5854            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5855        }
5856    }
5857
5858    private final boolean attachApplicationLocked(IApplicationThread thread,
5859            int pid) {
5860
5861        // Find the application record that is being attached...  either via
5862        // the pid if we are running in multiple processes, or just pull the
5863        // next app record if we are emulating process with anonymous threads.
5864        ProcessRecord app;
5865        if (pid != MY_PID && pid >= 0) {
5866            synchronized (mPidsSelfLocked) {
5867                app = mPidsSelfLocked.get(pid);
5868            }
5869        } else {
5870            app = null;
5871        }
5872
5873        if (app == null) {
5874            Slog.w(TAG, "No pending application record for pid " + pid
5875                    + " (IApplicationThread " + thread + "); dropping process");
5876            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5877            if (pid > 0 && pid != MY_PID) {
5878                Process.killProcessQuiet(pid);
5879                //TODO: Process.killProcessGroup(app.info.uid, pid);
5880            } else {
5881                try {
5882                    thread.scheduleExit();
5883                } catch (Exception e) {
5884                    // Ignore exceptions.
5885                }
5886            }
5887            return false;
5888        }
5889
5890        // If this application record is still attached to a previous
5891        // process, clean it up now.
5892        if (app.thread != null) {
5893            handleAppDiedLocked(app, true, true);
5894        }
5895
5896        // Tell the process all about itself.
5897
5898        if (localLOGV) Slog.v(
5899                TAG, "Binding process pid " + pid + " to record " + app);
5900
5901        final String processName = app.processName;
5902        try {
5903            AppDeathRecipient adr = new AppDeathRecipient(
5904                    app, pid, thread);
5905            thread.asBinder().linkToDeath(adr, 0);
5906            app.deathRecipient = adr;
5907        } catch (RemoteException e) {
5908            app.resetPackageList(mProcessStats);
5909            startProcessLocked(app, "link fail", processName);
5910            return false;
5911        }
5912
5913        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5914
5915        app.makeActive(thread, mProcessStats);
5916        app.curAdj = app.setAdj = -100;
5917        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5918        app.forcingToForeground = null;
5919        updateProcessForegroundLocked(app, false, false);
5920        app.hasShownUi = false;
5921        app.debugging = false;
5922        app.cached = false;
5923
5924        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5925
5926        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5927        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5928
5929        if (!normalMode) {
5930            Slog.i(TAG, "Launching preboot mode app: " + app);
5931        }
5932
5933        if (localLOGV) Slog.v(
5934            TAG, "New app record " + app
5935            + " thread=" + thread.asBinder() + " pid=" + pid);
5936        try {
5937            int testMode = IApplicationThread.DEBUG_OFF;
5938            if (mDebugApp != null && mDebugApp.equals(processName)) {
5939                testMode = mWaitForDebugger
5940                    ? IApplicationThread.DEBUG_WAIT
5941                    : IApplicationThread.DEBUG_ON;
5942                app.debugging = true;
5943                if (mDebugTransient) {
5944                    mDebugApp = mOrigDebugApp;
5945                    mWaitForDebugger = mOrigWaitForDebugger;
5946                }
5947            }
5948            String profileFile = app.instrumentationProfileFile;
5949            ParcelFileDescriptor profileFd = null;
5950            int samplingInterval = 0;
5951            boolean profileAutoStop = false;
5952            if (mProfileApp != null && mProfileApp.equals(processName)) {
5953                mProfileProc = app;
5954                profileFile = mProfileFile;
5955                profileFd = mProfileFd;
5956                samplingInterval = mSamplingInterval;
5957                profileAutoStop = mAutoStopProfiler;
5958            }
5959            boolean enableOpenGlTrace = false;
5960            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5961                enableOpenGlTrace = true;
5962                mOpenGlTraceApp = null;
5963            }
5964
5965            // If the app is being launched for restore or full backup, set it up specially
5966            boolean isRestrictedBackupMode = false;
5967            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5968                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5969                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5970                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5971            }
5972
5973            ensurePackageDexOpt(app.instrumentationInfo != null
5974                    ? app.instrumentationInfo.packageName
5975                    : app.info.packageName);
5976            if (app.instrumentationClass != null) {
5977                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5978            }
5979            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5980                    + processName + " with config " + mConfiguration);
5981            ApplicationInfo appInfo = app.instrumentationInfo != null
5982                    ? app.instrumentationInfo : app.info;
5983            app.compat = compatibilityInfoForPackageLocked(appInfo);
5984            if (profileFd != null) {
5985                profileFd = profileFd.dup();
5986            }
5987            ProfilerInfo profilerInfo = profileFile == null ? null
5988                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5989            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5990                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5991                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5992                    isRestrictedBackupMode || !normalMode, app.persistent,
5993                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5994                    mCoreSettingsObserver.getCoreSettingsLocked());
5995            updateLruProcessLocked(app, false, null);
5996            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5997        } catch (Exception e) {
5998            // todo: Yikes!  What should we do?  For now we will try to
5999            // start another process, but that could easily get us in
6000            // an infinite loop of restarting processes...
6001            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6002
6003            app.resetPackageList(mProcessStats);
6004            app.unlinkDeathRecipient();
6005            startProcessLocked(app, "bind fail", processName);
6006            return false;
6007        }
6008
6009        // Remove this record from the list of starting applications.
6010        mPersistentStartingProcesses.remove(app);
6011        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6012                "Attach application locked removing on hold: " + app);
6013        mProcessesOnHold.remove(app);
6014
6015        boolean badApp = false;
6016        boolean didSomething = false;
6017
6018        // See if the top visible activity is waiting to run in this process...
6019        if (normalMode) {
6020            try {
6021                if (mStackSupervisor.attachApplicationLocked(app)) {
6022                    didSomething = true;
6023                }
6024            } catch (Exception e) {
6025                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6026                badApp = true;
6027            }
6028        }
6029
6030        // Find any services that should be running in this process...
6031        if (!badApp) {
6032            try {
6033                didSomething |= mServices.attachApplicationLocked(app, processName);
6034            } catch (Exception e) {
6035                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6036                badApp = true;
6037            }
6038        }
6039
6040        // Check if a next-broadcast receiver is in this process...
6041        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6042            try {
6043                didSomething |= sendPendingBroadcastsLocked(app);
6044            } catch (Exception e) {
6045                // If the app died trying to launch the receiver we declare it 'bad'
6046                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6047                badApp = true;
6048            }
6049        }
6050
6051        // Check whether the next backup agent is in this process...
6052        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6053            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6054            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6055            try {
6056                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6057                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6058                        mBackupTarget.backupMode);
6059            } catch (Exception e) {
6060                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6061                badApp = true;
6062            }
6063        }
6064
6065        if (badApp) {
6066            app.kill("error during init", true);
6067            handleAppDiedLocked(app, false, true);
6068            return false;
6069        }
6070
6071        if (!didSomething) {
6072            updateOomAdjLocked();
6073        }
6074
6075        return true;
6076    }
6077
6078    @Override
6079    public final void attachApplication(IApplicationThread thread) {
6080        synchronized (this) {
6081            int callingPid = Binder.getCallingPid();
6082            final long origId = Binder.clearCallingIdentity();
6083            attachApplicationLocked(thread, callingPid);
6084            Binder.restoreCallingIdentity(origId);
6085        }
6086    }
6087
6088    @Override
6089    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6090        final long origId = Binder.clearCallingIdentity();
6091        synchronized (this) {
6092            ActivityStack stack = ActivityRecord.getStackLocked(token);
6093            if (stack != null) {
6094                ActivityRecord r =
6095                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6096                if (stopProfiling) {
6097                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6098                        try {
6099                            mProfileFd.close();
6100                        } catch (IOException e) {
6101                        }
6102                        clearProfilerLocked();
6103                    }
6104                }
6105            }
6106        }
6107        Binder.restoreCallingIdentity(origId);
6108    }
6109
6110    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6111        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6112                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6113    }
6114
6115    void enableScreenAfterBoot() {
6116        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6117                SystemClock.uptimeMillis());
6118        mWindowManager.enableScreenAfterBoot();
6119
6120        synchronized (this) {
6121            updateEventDispatchingLocked();
6122        }
6123    }
6124
6125    @Override
6126    public void showBootMessage(final CharSequence msg, final boolean always) {
6127        enforceNotIsolatedCaller("showBootMessage");
6128        mWindowManager.showBootMessage(msg, always);
6129    }
6130
6131    @Override
6132    public void keyguardWaitingForActivityDrawn() {
6133        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6134        final long token = Binder.clearCallingIdentity();
6135        try {
6136            synchronized (this) {
6137                if (DEBUG_LOCKSCREEN) logLockScreen("");
6138                mWindowManager.keyguardWaitingForActivityDrawn();
6139                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6140                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6141                }
6142            }
6143        } finally {
6144            Binder.restoreCallingIdentity(token);
6145        }
6146    }
6147
6148    final void finishBooting() {
6149        synchronized (this) {
6150            if (!mBootAnimationComplete) {
6151                mCallFinishBooting = true;
6152                return;
6153            }
6154            mCallFinishBooting = false;
6155        }
6156
6157        ArraySet<String> completedIsas = new ArraySet<String>();
6158        for (String abi : Build.SUPPORTED_ABIS) {
6159            Process.establishZygoteConnectionForAbi(abi);
6160            final String instructionSet = VMRuntime.getInstructionSet(abi);
6161            if (!completedIsas.contains(instructionSet)) {
6162                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6163                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6164                }
6165                completedIsas.add(instructionSet);
6166            }
6167        }
6168
6169        // Register receivers to handle package update events
6170        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6171
6172        // Let system services know.
6173        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6174
6175        synchronized (this) {
6176            // Ensure that any processes we had put on hold are now started
6177            // up.
6178            final int NP = mProcessesOnHold.size();
6179            if (NP > 0) {
6180                ArrayList<ProcessRecord> procs =
6181                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6182                for (int ip=0; ip<NP; ip++) {
6183                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6184                            + procs.get(ip));
6185                    startProcessLocked(procs.get(ip), "on-hold", null);
6186                }
6187            }
6188
6189            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6190                // Start looking for apps that are abusing wake locks.
6191                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6192                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6193                // Tell anyone interested that we are done booting!
6194                SystemProperties.set("sys.boot_completed", "1");
6195
6196                // And trigger dev.bootcomplete if we are not showing encryption progress
6197                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6198                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6199                    SystemProperties.set("dev.bootcomplete", "1");
6200                }
6201                for (int i=0; i<mStartedUsers.size(); i++) {
6202                    UserStartedState uss = mStartedUsers.valueAt(i);
6203                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6204                        uss.mState = UserStartedState.STATE_RUNNING;
6205                        final int userId = mStartedUsers.keyAt(i);
6206                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6207                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6208                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6209                        broadcastIntentLocked(null, null, intent, null,
6210                                new IIntentReceiver.Stub() {
6211                                    @Override
6212                                    public void performReceive(Intent intent, int resultCode,
6213                                            String data, Bundle extras, boolean ordered,
6214                                            boolean sticky, int sendingUser) {
6215                                        synchronized (ActivityManagerService.this) {
6216                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6217                                                    true, false);
6218                                        }
6219                                    }
6220                                },
6221                                0, null, null,
6222                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6223                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6224                                userId);
6225                    }
6226                }
6227                scheduleStartProfilesLocked();
6228            }
6229        }
6230    }
6231
6232    @Override
6233    public void bootAnimationComplete() {
6234        final boolean callFinishBooting;
6235        synchronized (this) {
6236            callFinishBooting = mCallFinishBooting;
6237            mBootAnimationComplete = true;
6238        }
6239        if (callFinishBooting) {
6240            finishBooting();
6241        }
6242    }
6243
6244    final void ensureBootCompleted() {
6245        boolean booting;
6246        boolean enableScreen;
6247        synchronized (this) {
6248            booting = mBooting;
6249            mBooting = false;
6250            enableScreen = !mBooted;
6251            mBooted = true;
6252        }
6253
6254        if (booting) {
6255            finishBooting();
6256        }
6257
6258        if (enableScreen) {
6259            enableScreenAfterBoot();
6260        }
6261    }
6262
6263    @Override
6264    public final void activityResumed(IBinder token) {
6265        final long origId = Binder.clearCallingIdentity();
6266        synchronized(this) {
6267            ActivityStack stack = ActivityRecord.getStackLocked(token);
6268            if (stack != null) {
6269                ActivityRecord.activityResumedLocked(token);
6270            }
6271        }
6272        Binder.restoreCallingIdentity(origId);
6273    }
6274
6275    @Override
6276    public final void activityPaused(IBinder token) {
6277        final long origId = Binder.clearCallingIdentity();
6278        synchronized(this) {
6279            ActivityStack stack = ActivityRecord.getStackLocked(token);
6280            if (stack != null) {
6281                stack.activityPausedLocked(token, false);
6282            }
6283        }
6284        Binder.restoreCallingIdentity(origId);
6285    }
6286
6287    @Override
6288    public final void activityStopped(IBinder token, Bundle icicle,
6289            PersistableBundle persistentState, CharSequence description) {
6290        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6291
6292        // Refuse possible leaked file descriptors
6293        if (icicle != null && icicle.hasFileDescriptors()) {
6294            throw new IllegalArgumentException("File descriptors passed in Bundle");
6295        }
6296
6297        final long origId = Binder.clearCallingIdentity();
6298
6299        synchronized (this) {
6300            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6301            if (r != null) {
6302                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6303            }
6304        }
6305
6306        trimApplications();
6307
6308        Binder.restoreCallingIdentity(origId);
6309    }
6310
6311    @Override
6312    public final void activityDestroyed(IBinder token) {
6313        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6314        synchronized (this) {
6315            ActivityStack stack = ActivityRecord.getStackLocked(token);
6316            if (stack != null) {
6317                stack.activityDestroyedLocked(token);
6318            }
6319        }
6320    }
6321
6322    @Override
6323    public final void backgroundResourcesReleased(IBinder token) {
6324        final long origId = Binder.clearCallingIdentity();
6325        try {
6326            synchronized (this) {
6327                ActivityStack stack = ActivityRecord.getStackLocked(token);
6328                if (stack != null) {
6329                    stack.backgroundResourcesReleased(token);
6330                }
6331            }
6332        } finally {
6333            Binder.restoreCallingIdentity(origId);
6334        }
6335    }
6336
6337    @Override
6338    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6339        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6340    }
6341
6342    @Override
6343    public final void notifyEnterAnimationComplete(IBinder token) {
6344        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6345    }
6346
6347    @Override
6348    public String getCallingPackage(IBinder token) {
6349        synchronized (this) {
6350            ActivityRecord r = getCallingRecordLocked(token);
6351            return r != null ? r.info.packageName : null;
6352        }
6353    }
6354
6355    @Override
6356    public ComponentName getCallingActivity(IBinder token) {
6357        synchronized (this) {
6358            ActivityRecord r = getCallingRecordLocked(token);
6359            return r != null ? r.intent.getComponent() : null;
6360        }
6361    }
6362
6363    private ActivityRecord getCallingRecordLocked(IBinder token) {
6364        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6365        if (r == null) {
6366            return null;
6367        }
6368        return r.resultTo;
6369    }
6370
6371    @Override
6372    public ComponentName getActivityClassForToken(IBinder token) {
6373        synchronized(this) {
6374            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6375            if (r == null) {
6376                return null;
6377            }
6378            return r.intent.getComponent();
6379        }
6380    }
6381
6382    @Override
6383    public String getPackageForToken(IBinder token) {
6384        synchronized(this) {
6385            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6386            if (r == null) {
6387                return null;
6388            }
6389            return r.packageName;
6390        }
6391    }
6392
6393    @Override
6394    public IIntentSender getIntentSender(int type,
6395            String packageName, IBinder token, String resultWho,
6396            int requestCode, Intent[] intents, String[] resolvedTypes,
6397            int flags, Bundle options, int userId) {
6398        enforceNotIsolatedCaller("getIntentSender");
6399        // Refuse possible leaked file descriptors
6400        if (intents != null) {
6401            if (intents.length < 1) {
6402                throw new IllegalArgumentException("Intents array length must be >= 1");
6403            }
6404            for (int i=0; i<intents.length; i++) {
6405                Intent intent = intents[i];
6406                if (intent != null) {
6407                    if (intent.hasFileDescriptors()) {
6408                        throw new IllegalArgumentException("File descriptors passed in Intent");
6409                    }
6410                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6411                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6412                        throw new IllegalArgumentException(
6413                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6414                    }
6415                    intents[i] = new Intent(intent);
6416                }
6417            }
6418            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6419                throw new IllegalArgumentException(
6420                        "Intent array length does not match resolvedTypes length");
6421            }
6422        }
6423        if (options != null) {
6424            if (options.hasFileDescriptors()) {
6425                throw new IllegalArgumentException("File descriptors passed in options");
6426            }
6427        }
6428
6429        synchronized(this) {
6430            int callingUid = Binder.getCallingUid();
6431            int origUserId = userId;
6432            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6433                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6434                    ALLOW_NON_FULL, "getIntentSender", null);
6435            if (origUserId == UserHandle.USER_CURRENT) {
6436                // We don't want to evaluate this until the pending intent is
6437                // actually executed.  However, we do want to always do the
6438                // security checking for it above.
6439                userId = UserHandle.USER_CURRENT;
6440            }
6441            try {
6442                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6443                    int uid = AppGlobals.getPackageManager()
6444                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6445                    if (!UserHandle.isSameApp(callingUid, uid)) {
6446                        String msg = "Permission Denial: getIntentSender() from pid="
6447                            + Binder.getCallingPid()
6448                            + ", uid=" + Binder.getCallingUid()
6449                            + ", (need uid=" + uid + ")"
6450                            + " is not allowed to send as package " + packageName;
6451                        Slog.w(TAG, msg);
6452                        throw new SecurityException(msg);
6453                    }
6454                }
6455
6456                return getIntentSenderLocked(type, packageName, callingUid, userId,
6457                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6458
6459            } catch (RemoteException e) {
6460                throw new SecurityException(e);
6461            }
6462        }
6463    }
6464
6465    IIntentSender getIntentSenderLocked(int type, String packageName,
6466            int callingUid, int userId, IBinder token, String resultWho,
6467            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6468            Bundle options) {
6469        if (DEBUG_MU)
6470            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6471        ActivityRecord activity = null;
6472        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6473            activity = ActivityRecord.isInStackLocked(token);
6474            if (activity == null) {
6475                return null;
6476            }
6477            if (activity.finishing) {
6478                return null;
6479            }
6480        }
6481
6482        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6483        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6484        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6485        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6486                |PendingIntent.FLAG_UPDATE_CURRENT);
6487
6488        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6489                type, packageName, activity, resultWho,
6490                requestCode, intents, resolvedTypes, flags, options, userId);
6491        WeakReference<PendingIntentRecord> ref;
6492        ref = mIntentSenderRecords.get(key);
6493        PendingIntentRecord rec = ref != null ? ref.get() : null;
6494        if (rec != null) {
6495            if (!cancelCurrent) {
6496                if (updateCurrent) {
6497                    if (rec.key.requestIntent != null) {
6498                        rec.key.requestIntent.replaceExtras(intents != null ?
6499                                intents[intents.length - 1] : null);
6500                    }
6501                    if (intents != null) {
6502                        intents[intents.length-1] = rec.key.requestIntent;
6503                        rec.key.allIntents = intents;
6504                        rec.key.allResolvedTypes = resolvedTypes;
6505                    } else {
6506                        rec.key.allIntents = null;
6507                        rec.key.allResolvedTypes = null;
6508                    }
6509                }
6510                return rec;
6511            }
6512            rec.canceled = true;
6513            mIntentSenderRecords.remove(key);
6514        }
6515        if (noCreate) {
6516            return rec;
6517        }
6518        rec = new PendingIntentRecord(this, key, callingUid);
6519        mIntentSenderRecords.put(key, rec.ref);
6520        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6521            if (activity.pendingResults == null) {
6522                activity.pendingResults
6523                        = new HashSet<WeakReference<PendingIntentRecord>>();
6524            }
6525            activity.pendingResults.add(rec.ref);
6526        }
6527        return rec;
6528    }
6529
6530    @Override
6531    public void cancelIntentSender(IIntentSender sender) {
6532        if (!(sender instanceof PendingIntentRecord)) {
6533            return;
6534        }
6535        synchronized(this) {
6536            PendingIntentRecord rec = (PendingIntentRecord)sender;
6537            try {
6538                int uid = AppGlobals.getPackageManager()
6539                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6540                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6541                    String msg = "Permission Denial: cancelIntentSender() from pid="
6542                        + Binder.getCallingPid()
6543                        + ", uid=" + Binder.getCallingUid()
6544                        + " is not allowed to cancel packges "
6545                        + rec.key.packageName;
6546                    Slog.w(TAG, msg);
6547                    throw new SecurityException(msg);
6548                }
6549            } catch (RemoteException e) {
6550                throw new SecurityException(e);
6551            }
6552            cancelIntentSenderLocked(rec, true);
6553        }
6554    }
6555
6556    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6557        rec.canceled = true;
6558        mIntentSenderRecords.remove(rec.key);
6559        if (cleanActivity && rec.key.activity != null) {
6560            rec.key.activity.pendingResults.remove(rec.ref);
6561        }
6562    }
6563
6564    @Override
6565    public String getPackageForIntentSender(IIntentSender pendingResult) {
6566        if (!(pendingResult instanceof PendingIntentRecord)) {
6567            return null;
6568        }
6569        try {
6570            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6571            return res.key.packageName;
6572        } catch (ClassCastException e) {
6573        }
6574        return null;
6575    }
6576
6577    @Override
6578    public int getUidForIntentSender(IIntentSender sender) {
6579        if (sender instanceof PendingIntentRecord) {
6580            try {
6581                PendingIntentRecord res = (PendingIntentRecord)sender;
6582                return res.uid;
6583            } catch (ClassCastException e) {
6584            }
6585        }
6586        return -1;
6587    }
6588
6589    @Override
6590    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6591        if (!(pendingResult instanceof PendingIntentRecord)) {
6592            return false;
6593        }
6594        try {
6595            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6596            if (res.key.allIntents == null) {
6597                return false;
6598            }
6599            for (int i=0; i<res.key.allIntents.length; i++) {
6600                Intent intent = res.key.allIntents[i];
6601                if (intent.getPackage() != null && intent.getComponent() != null) {
6602                    return false;
6603                }
6604            }
6605            return true;
6606        } catch (ClassCastException e) {
6607        }
6608        return false;
6609    }
6610
6611    @Override
6612    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6613        if (!(pendingResult instanceof PendingIntentRecord)) {
6614            return false;
6615        }
6616        try {
6617            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6618            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6619                return true;
6620            }
6621            return false;
6622        } catch (ClassCastException e) {
6623        }
6624        return false;
6625    }
6626
6627    @Override
6628    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6629        if (!(pendingResult instanceof PendingIntentRecord)) {
6630            return null;
6631        }
6632        try {
6633            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6634            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6635        } catch (ClassCastException e) {
6636        }
6637        return null;
6638    }
6639
6640    @Override
6641    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6642        if (!(pendingResult instanceof PendingIntentRecord)) {
6643            return null;
6644        }
6645        try {
6646            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6647            Intent intent = res.key.requestIntent;
6648            if (intent != null) {
6649                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6650                        || res.lastTagPrefix.equals(prefix))) {
6651                    return res.lastTag;
6652                }
6653                res.lastTagPrefix = prefix;
6654                StringBuilder sb = new StringBuilder(128);
6655                if (prefix != null) {
6656                    sb.append(prefix);
6657                }
6658                if (intent.getAction() != null) {
6659                    sb.append(intent.getAction());
6660                } else if (intent.getComponent() != null) {
6661                    intent.getComponent().appendShortString(sb);
6662                } else {
6663                    sb.append("?");
6664                }
6665                return res.lastTag = sb.toString();
6666            }
6667        } catch (ClassCastException e) {
6668        }
6669        return null;
6670    }
6671
6672    @Override
6673    public void setProcessLimit(int max) {
6674        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6675                "setProcessLimit()");
6676        synchronized (this) {
6677            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6678            mProcessLimitOverride = max;
6679        }
6680        trimApplications();
6681    }
6682
6683    @Override
6684    public int getProcessLimit() {
6685        synchronized (this) {
6686            return mProcessLimitOverride;
6687        }
6688    }
6689
6690    void foregroundTokenDied(ForegroundToken token) {
6691        synchronized (ActivityManagerService.this) {
6692            synchronized (mPidsSelfLocked) {
6693                ForegroundToken cur
6694                    = mForegroundProcesses.get(token.pid);
6695                if (cur != token) {
6696                    return;
6697                }
6698                mForegroundProcesses.remove(token.pid);
6699                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6700                if (pr == null) {
6701                    return;
6702                }
6703                pr.forcingToForeground = null;
6704                updateProcessForegroundLocked(pr, false, false);
6705            }
6706            updateOomAdjLocked();
6707        }
6708    }
6709
6710    @Override
6711    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6712        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6713                "setProcessForeground()");
6714        synchronized(this) {
6715            boolean changed = false;
6716
6717            synchronized (mPidsSelfLocked) {
6718                ProcessRecord pr = mPidsSelfLocked.get(pid);
6719                if (pr == null && isForeground) {
6720                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6721                    return;
6722                }
6723                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6724                if (oldToken != null) {
6725                    oldToken.token.unlinkToDeath(oldToken, 0);
6726                    mForegroundProcesses.remove(pid);
6727                    if (pr != null) {
6728                        pr.forcingToForeground = null;
6729                    }
6730                    changed = true;
6731                }
6732                if (isForeground && token != null) {
6733                    ForegroundToken newToken = new ForegroundToken() {
6734                        @Override
6735                        public void binderDied() {
6736                            foregroundTokenDied(this);
6737                        }
6738                    };
6739                    newToken.pid = pid;
6740                    newToken.token = token;
6741                    try {
6742                        token.linkToDeath(newToken, 0);
6743                        mForegroundProcesses.put(pid, newToken);
6744                        pr.forcingToForeground = token;
6745                        changed = true;
6746                    } catch (RemoteException e) {
6747                        // If the process died while doing this, we will later
6748                        // do the cleanup with the process death link.
6749                    }
6750                }
6751            }
6752
6753            if (changed) {
6754                updateOomAdjLocked();
6755            }
6756        }
6757    }
6758
6759    // =========================================================
6760    // PERMISSIONS
6761    // =========================================================
6762
6763    static class PermissionController extends IPermissionController.Stub {
6764        ActivityManagerService mActivityManagerService;
6765        PermissionController(ActivityManagerService activityManagerService) {
6766            mActivityManagerService = activityManagerService;
6767        }
6768
6769        @Override
6770        public boolean checkPermission(String permission, int pid, int uid) {
6771            return mActivityManagerService.checkPermission(permission, pid,
6772                    uid) == PackageManager.PERMISSION_GRANTED;
6773        }
6774    }
6775
6776    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6777        @Override
6778        public int checkComponentPermission(String permission, int pid, int uid,
6779                int owningUid, boolean exported) {
6780            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6781                    owningUid, exported);
6782        }
6783
6784        @Override
6785        public Object getAMSLock() {
6786            return ActivityManagerService.this;
6787        }
6788    }
6789
6790    /**
6791     * This can be called with or without the global lock held.
6792     */
6793    int checkComponentPermission(String permission, int pid, int uid,
6794            int owningUid, boolean exported) {
6795        // We might be performing an operation on behalf of an indirect binder
6796        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6797        // client identity accordingly before proceeding.
6798        Identity tlsIdentity = sCallerIdentity.get();
6799        if (tlsIdentity != null) {
6800            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6801                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6802            uid = tlsIdentity.uid;
6803            pid = tlsIdentity.pid;
6804        }
6805
6806        if (pid == MY_PID) {
6807            return PackageManager.PERMISSION_GRANTED;
6808        }
6809
6810        return ActivityManager.checkComponentPermission(permission, uid,
6811                owningUid, exported);
6812    }
6813
6814    /**
6815     * As the only public entry point for permissions checking, this method
6816     * can enforce the semantic that requesting a check on a null global
6817     * permission is automatically denied.  (Internally a null permission
6818     * string is used when calling {@link #checkComponentPermission} in cases
6819     * when only uid-based security is needed.)
6820     *
6821     * This can be called with or without the global lock held.
6822     */
6823    @Override
6824    public int checkPermission(String permission, int pid, int uid) {
6825        if (permission == null) {
6826            return PackageManager.PERMISSION_DENIED;
6827        }
6828        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6829    }
6830
6831    /**
6832     * Binder IPC calls go through the public entry point.
6833     * This can be called with or without the global lock held.
6834     */
6835    int checkCallingPermission(String permission) {
6836        return checkPermission(permission,
6837                Binder.getCallingPid(),
6838                UserHandle.getAppId(Binder.getCallingUid()));
6839    }
6840
6841    /**
6842     * This can be called with or without the global lock held.
6843     */
6844    void enforceCallingPermission(String permission, String func) {
6845        if (checkCallingPermission(permission)
6846                == PackageManager.PERMISSION_GRANTED) {
6847            return;
6848        }
6849
6850        String msg = "Permission Denial: " + func + " from pid="
6851                + Binder.getCallingPid()
6852                + ", uid=" + Binder.getCallingUid()
6853                + " requires " + permission;
6854        Slog.w(TAG, msg);
6855        throw new SecurityException(msg);
6856    }
6857
6858    /**
6859     * Determine if UID is holding permissions required to access {@link Uri} in
6860     * the given {@link ProviderInfo}. Final permission checking is always done
6861     * in {@link ContentProvider}.
6862     */
6863    private final boolean checkHoldingPermissionsLocked(
6864            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6865        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6866                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6867        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6868            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6869                    != PERMISSION_GRANTED) {
6870                return false;
6871            }
6872        }
6873        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6874    }
6875
6876    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6877            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6878        if (pi.applicationInfo.uid == uid) {
6879            return true;
6880        } else if (!pi.exported) {
6881            return false;
6882        }
6883
6884        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6885        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6886        try {
6887            // check if target holds top-level <provider> permissions
6888            if (!readMet && pi.readPermission != null && considerUidPermissions
6889                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6890                readMet = true;
6891            }
6892            if (!writeMet && pi.writePermission != null && considerUidPermissions
6893                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6894                writeMet = true;
6895            }
6896
6897            // track if unprotected read/write is allowed; any denied
6898            // <path-permission> below removes this ability
6899            boolean allowDefaultRead = pi.readPermission == null;
6900            boolean allowDefaultWrite = pi.writePermission == null;
6901
6902            // check if target holds any <path-permission> that match uri
6903            final PathPermission[] pps = pi.pathPermissions;
6904            if (pps != null) {
6905                final String path = grantUri.uri.getPath();
6906                int i = pps.length;
6907                while (i > 0 && (!readMet || !writeMet)) {
6908                    i--;
6909                    PathPermission pp = pps[i];
6910                    if (pp.match(path)) {
6911                        if (!readMet) {
6912                            final String pprperm = pp.getReadPermission();
6913                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6914                                    + pprperm + " for " + pp.getPath()
6915                                    + ": match=" + pp.match(path)
6916                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6917                            if (pprperm != null) {
6918                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6919                                        == PERMISSION_GRANTED) {
6920                                    readMet = true;
6921                                } else {
6922                                    allowDefaultRead = false;
6923                                }
6924                            }
6925                        }
6926                        if (!writeMet) {
6927                            final String ppwperm = pp.getWritePermission();
6928                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6929                                    + ppwperm + " for " + pp.getPath()
6930                                    + ": match=" + pp.match(path)
6931                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6932                            if (ppwperm != null) {
6933                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6934                                        == PERMISSION_GRANTED) {
6935                                    writeMet = true;
6936                                } else {
6937                                    allowDefaultWrite = false;
6938                                }
6939                            }
6940                        }
6941                    }
6942                }
6943            }
6944
6945            // grant unprotected <provider> read/write, if not blocked by
6946            // <path-permission> above
6947            if (allowDefaultRead) readMet = true;
6948            if (allowDefaultWrite) writeMet = true;
6949
6950        } catch (RemoteException e) {
6951            return false;
6952        }
6953
6954        return readMet && writeMet;
6955    }
6956
6957    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6958        ProviderInfo pi = null;
6959        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6960        if (cpr != null) {
6961            pi = cpr.info;
6962        } else {
6963            try {
6964                pi = AppGlobals.getPackageManager().resolveContentProvider(
6965                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6966            } catch (RemoteException ex) {
6967            }
6968        }
6969        return pi;
6970    }
6971
6972    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6973        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6974        if (targetUris != null) {
6975            return targetUris.get(grantUri);
6976        }
6977        return null;
6978    }
6979
6980    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6981            String targetPkg, int targetUid, GrantUri grantUri) {
6982        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6983        if (targetUris == null) {
6984            targetUris = Maps.newArrayMap();
6985            mGrantedUriPermissions.put(targetUid, targetUris);
6986        }
6987
6988        UriPermission perm = targetUris.get(grantUri);
6989        if (perm == null) {
6990            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6991            targetUris.put(grantUri, perm);
6992        }
6993
6994        return perm;
6995    }
6996
6997    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6998            final int modeFlags) {
6999        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7000        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7001                : UriPermission.STRENGTH_OWNED;
7002
7003        // Root gets to do everything.
7004        if (uid == 0) {
7005            return true;
7006        }
7007
7008        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7009        if (perms == null) return false;
7010
7011        // First look for exact match
7012        final UriPermission exactPerm = perms.get(grantUri);
7013        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7014            return true;
7015        }
7016
7017        // No exact match, look for prefixes
7018        final int N = perms.size();
7019        for (int i = 0; i < N; i++) {
7020            final UriPermission perm = perms.valueAt(i);
7021            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7022                    && perm.getStrength(modeFlags) >= minStrength) {
7023                return true;
7024            }
7025        }
7026
7027        return false;
7028    }
7029
7030    /**
7031     * @param uri This uri must NOT contain an embedded userId.
7032     * @param userId The userId in which the uri is to be resolved.
7033     */
7034    @Override
7035    public int checkUriPermission(Uri uri, int pid, int uid,
7036            final int modeFlags, int userId) {
7037        enforceNotIsolatedCaller("checkUriPermission");
7038
7039        // Another redirected-binder-call permissions check as in
7040        // {@link checkComponentPermission}.
7041        Identity tlsIdentity = sCallerIdentity.get();
7042        if (tlsIdentity != null) {
7043            uid = tlsIdentity.uid;
7044            pid = tlsIdentity.pid;
7045        }
7046
7047        // Our own process gets to do everything.
7048        if (pid == MY_PID) {
7049            return PackageManager.PERMISSION_GRANTED;
7050        }
7051        synchronized (this) {
7052            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7053                    ? PackageManager.PERMISSION_GRANTED
7054                    : PackageManager.PERMISSION_DENIED;
7055        }
7056    }
7057
7058    /**
7059     * Check if the targetPkg can be granted permission to access uri by
7060     * the callingUid using the given modeFlags.  Throws a security exception
7061     * if callingUid is not allowed to do this.  Returns the uid of the target
7062     * if the URI permission grant should be performed; returns -1 if it is not
7063     * needed (for example targetPkg already has permission to access the URI).
7064     * If you already know the uid of the target, you can supply it in
7065     * lastTargetUid else set that to -1.
7066     */
7067    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7068            final int modeFlags, int lastTargetUid) {
7069        if (!Intent.isAccessUriMode(modeFlags)) {
7070            return -1;
7071        }
7072
7073        if (targetPkg != null) {
7074            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7075                    "Checking grant " + targetPkg + " permission to " + grantUri);
7076        }
7077
7078        final IPackageManager pm = AppGlobals.getPackageManager();
7079
7080        // If this is not a content: uri, we can't do anything with it.
7081        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7082            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7083                    "Can't grant URI permission for non-content URI: " + grantUri);
7084            return -1;
7085        }
7086
7087        final String authority = grantUri.uri.getAuthority();
7088        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7089        if (pi == null) {
7090            Slog.w(TAG, "No content provider found for permission check: " +
7091                    grantUri.uri.toSafeString());
7092            return -1;
7093        }
7094
7095        int targetUid = lastTargetUid;
7096        if (targetUid < 0 && targetPkg != null) {
7097            try {
7098                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7099                if (targetUid < 0) {
7100                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7101                            "Can't grant URI permission no uid for: " + targetPkg);
7102                    return -1;
7103                }
7104            } catch (RemoteException ex) {
7105                return -1;
7106            }
7107        }
7108
7109        if (targetUid >= 0) {
7110            // First...  does the target actually need this permission?
7111            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7112                // No need to grant the target this permission.
7113                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7114                        "Target " + targetPkg + " already has full permission to " + grantUri);
7115                return -1;
7116            }
7117        } else {
7118            // First...  there is no target package, so can anyone access it?
7119            boolean allowed = pi.exported;
7120            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7121                if (pi.readPermission != null) {
7122                    allowed = false;
7123                }
7124            }
7125            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7126                if (pi.writePermission != null) {
7127                    allowed = false;
7128                }
7129            }
7130            if (allowed) {
7131                return -1;
7132            }
7133        }
7134
7135        /* There is a special cross user grant if:
7136         * - The target is on another user.
7137         * - Apps on the current user can access the uri without any uid permissions.
7138         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7139         * grant uri permissions.
7140         */
7141        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7142                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7143                modeFlags, false /*without considering the uid permissions*/);
7144
7145        // Second...  is the provider allowing granting of URI permissions?
7146        if (!specialCrossUserGrant) {
7147            if (!pi.grantUriPermissions) {
7148                throw new SecurityException("Provider " + pi.packageName
7149                        + "/" + pi.name
7150                        + " does not allow granting of Uri permissions (uri "
7151                        + grantUri + ")");
7152            }
7153            if (pi.uriPermissionPatterns != null) {
7154                final int N = pi.uriPermissionPatterns.length;
7155                boolean allowed = false;
7156                for (int i=0; i<N; i++) {
7157                    if (pi.uriPermissionPatterns[i] != null
7158                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7159                        allowed = true;
7160                        break;
7161                    }
7162                }
7163                if (!allowed) {
7164                    throw new SecurityException("Provider " + pi.packageName
7165                            + "/" + pi.name
7166                            + " does not allow granting of permission to path of Uri "
7167                            + grantUri);
7168                }
7169            }
7170        }
7171
7172        // Third...  does the caller itself have permission to access
7173        // this uri?
7174        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7175            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7176                // Require they hold a strong enough Uri permission
7177                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7178                    throw new SecurityException("Uid " + callingUid
7179                            + " does not have permission to uri " + grantUri);
7180                }
7181            }
7182        }
7183        return targetUid;
7184    }
7185
7186    /**
7187     * @param uri This uri must NOT contain an embedded userId.
7188     * @param userId The userId in which the uri is to be resolved.
7189     */
7190    @Override
7191    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7192            final int modeFlags, int userId) {
7193        enforceNotIsolatedCaller("checkGrantUriPermission");
7194        synchronized(this) {
7195            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7196                    new GrantUri(userId, uri, false), modeFlags, -1);
7197        }
7198    }
7199
7200    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7201            final int modeFlags, UriPermissionOwner owner) {
7202        if (!Intent.isAccessUriMode(modeFlags)) {
7203            return;
7204        }
7205
7206        // So here we are: the caller has the assumed permission
7207        // to the uri, and the target doesn't.  Let's now give this to
7208        // the target.
7209
7210        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7211                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7212
7213        final String authority = grantUri.uri.getAuthority();
7214        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7215        if (pi == null) {
7216            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7217            return;
7218        }
7219
7220        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7221            grantUri.prefix = true;
7222        }
7223        final UriPermission perm = findOrCreateUriPermissionLocked(
7224                pi.packageName, targetPkg, targetUid, grantUri);
7225        perm.grantModes(modeFlags, owner);
7226    }
7227
7228    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7229            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7230        if (targetPkg == null) {
7231            throw new NullPointerException("targetPkg");
7232        }
7233        int targetUid;
7234        final IPackageManager pm = AppGlobals.getPackageManager();
7235        try {
7236            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7237        } catch (RemoteException ex) {
7238            return;
7239        }
7240
7241        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7242                targetUid);
7243        if (targetUid < 0) {
7244            return;
7245        }
7246
7247        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7248                owner);
7249    }
7250
7251    static class NeededUriGrants extends ArrayList<GrantUri> {
7252        final String targetPkg;
7253        final int targetUid;
7254        final int flags;
7255
7256        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7257            this.targetPkg = targetPkg;
7258            this.targetUid = targetUid;
7259            this.flags = flags;
7260        }
7261    }
7262
7263    /**
7264     * Like checkGrantUriPermissionLocked, but takes an Intent.
7265     */
7266    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7267            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7268        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7269                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7270                + " clip=" + (intent != null ? intent.getClipData() : null)
7271                + " from " + intent + "; flags=0x"
7272                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7273
7274        if (targetPkg == null) {
7275            throw new NullPointerException("targetPkg");
7276        }
7277
7278        if (intent == null) {
7279            return null;
7280        }
7281        Uri data = intent.getData();
7282        ClipData clip = intent.getClipData();
7283        if (data == null && clip == null) {
7284            return null;
7285        }
7286        // Default userId for uris in the intent (if they don't specify it themselves)
7287        int contentUserHint = intent.getContentUserHint();
7288        if (contentUserHint == UserHandle.USER_CURRENT) {
7289            contentUserHint = UserHandle.getUserId(callingUid);
7290        }
7291        final IPackageManager pm = AppGlobals.getPackageManager();
7292        int targetUid;
7293        if (needed != null) {
7294            targetUid = needed.targetUid;
7295        } else {
7296            try {
7297                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7298            } catch (RemoteException ex) {
7299                return null;
7300            }
7301            if (targetUid < 0) {
7302                if (DEBUG_URI_PERMISSION) {
7303                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7304                            + " on user " + targetUserId);
7305                }
7306                return null;
7307            }
7308        }
7309        if (data != null) {
7310            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7311            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7312                    targetUid);
7313            if (targetUid > 0) {
7314                if (needed == null) {
7315                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7316                }
7317                needed.add(grantUri);
7318            }
7319        }
7320        if (clip != null) {
7321            for (int i=0; i<clip.getItemCount(); i++) {
7322                Uri uri = clip.getItemAt(i).getUri();
7323                if (uri != null) {
7324                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7325                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7326                            targetUid);
7327                    if (targetUid > 0) {
7328                        if (needed == null) {
7329                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7330                        }
7331                        needed.add(grantUri);
7332                    }
7333                } else {
7334                    Intent clipIntent = clip.getItemAt(i).getIntent();
7335                    if (clipIntent != null) {
7336                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7337                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7338                        if (newNeeded != null) {
7339                            needed = newNeeded;
7340                        }
7341                    }
7342                }
7343            }
7344        }
7345
7346        return needed;
7347    }
7348
7349    /**
7350     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7351     */
7352    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7353            UriPermissionOwner owner) {
7354        if (needed != null) {
7355            for (int i=0; i<needed.size(); i++) {
7356                GrantUri grantUri = needed.get(i);
7357                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7358                        grantUri, needed.flags, owner);
7359            }
7360        }
7361    }
7362
7363    void grantUriPermissionFromIntentLocked(int callingUid,
7364            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7365        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7366                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7367        if (needed == null) {
7368            return;
7369        }
7370
7371        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7372    }
7373
7374    /**
7375     * @param uri This uri must NOT contain an embedded userId.
7376     * @param userId The userId in which the uri is to be resolved.
7377     */
7378    @Override
7379    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7380            final int modeFlags, int userId) {
7381        enforceNotIsolatedCaller("grantUriPermission");
7382        GrantUri grantUri = new GrantUri(userId, uri, false);
7383        synchronized(this) {
7384            final ProcessRecord r = getRecordForAppLocked(caller);
7385            if (r == null) {
7386                throw new SecurityException("Unable to find app for caller "
7387                        + caller
7388                        + " when granting permission to uri " + grantUri);
7389            }
7390            if (targetPkg == null) {
7391                throw new IllegalArgumentException("null target");
7392            }
7393            if (grantUri == null) {
7394                throw new IllegalArgumentException("null uri");
7395            }
7396
7397            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7398                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7399                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7400                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7401
7402            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7403                    UserHandle.getUserId(r.uid));
7404        }
7405    }
7406
7407    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7408        if (perm.modeFlags == 0) {
7409            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7410                    perm.targetUid);
7411            if (perms != null) {
7412                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7413                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7414
7415                perms.remove(perm.uri);
7416                if (perms.isEmpty()) {
7417                    mGrantedUriPermissions.remove(perm.targetUid);
7418                }
7419            }
7420        }
7421    }
7422
7423    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7424        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7425
7426        final IPackageManager pm = AppGlobals.getPackageManager();
7427        final String authority = grantUri.uri.getAuthority();
7428        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7429        if (pi == null) {
7430            Slog.w(TAG, "No content provider found for permission revoke: "
7431                    + grantUri.toSafeString());
7432            return;
7433        }
7434
7435        // Does the caller have this permission on the URI?
7436        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7437            // If they don't have direct access to the URI, then revoke any
7438            // ownerless URI permissions that have been granted to them.
7439            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7440            if (perms != null) {
7441                boolean persistChanged = false;
7442                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7443                    final UriPermission perm = it.next();
7444                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7445                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7446                        if (DEBUG_URI_PERMISSION)
7447                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7448                                    " permission to " + perm.uri);
7449                        persistChanged |= perm.revokeModes(
7450                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7451                        if (perm.modeFlags == 0) {
7452                            it.remove();
7453                        }
7454                    }
7455                }
7456                if (perms.isEmpty()) {
7457                    mGrantedUriPermissions.remove(callingUid);
7458                }
7459                if (persistChanged) {
7460                    schedulePersistUriGrants();
7461                }
7462            }
7463            return;
7464        }
7465
7466        boolean persistChanged = false;
7467
7468        // Go through all of the permissions and remove any that match.
7469        int N = mGrantedUriPermissions.size();
7470        for (int i = 0; i < N; i++) {
7471            final int targetUid = mGrantedUriPermissions.keyAt(i);
7472            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7473
7474            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7475                final UriPermission perm = it.next();
7476                if (perm.uri.sourceUserId == grantUri.sourceUserId
7477                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7478                    if (DEBUG_URI_PERMISSION)
7479                        Slog.v(TAG,
7480                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7481                    persistChanged |= perm.revokeModes(
7482                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7483                    if (perm.modeFlags == 0) {
7484                        it.remove();
7485                    }
7486                }
7487            }
7488
7489            if (perms.isEmpty()) {
7490                mGrantedUriPermissions.remove(targetUid);
7491                N--;
7492                i--;
7493            }
7494        }
7495
7496        if (persistChanged) {
7497            schedulePersistUriGrants();
7498        }
7499    }
7500
7501    /**
7502     * @param uri This uri must NOT contain an embedded userId.
7503     * @param userId The userId in which the uri is to be resolved.
7504     */
7505    @Override
7506    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7507            int userId) {
7508        enforceNotIsolatedCaller("revokeUriPermission");
7509        synchronized(this) {
7510            final ProcessRecord r = getRecordForAppLocked(caller);
7511            if (r == null) {
7512                throw new SecurityException("Unable to find app for caller "
7513                        + caller
7514                        + " when revoking permission to uri " + uri);
7515            }
7516            if (uri == null) {
7517                Slog.w(TAG, "revokeUriPermission: null uri");
7518                return;
7519            }
7520
7521            if (!Intent.isAccessUriMode(modeFlags)) {
7522                return;
7523            }
7524
7525            final IPackageManager pm = AppGlobals.getPackageManager();
7526            final String authority = uri.getAuthority();
7527            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7528            if (pi == null) {
7529                Slog.w(TAG, "No content provider found for permission revoke: "
7530                        + uri.toSafeString());
7531                return;
7532            }
7533
7534            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7535        }
7536    }
7537
7538    /**
7539     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7540     * given package.
7541     *
7542     * @param packageName Package name to match, or {@code null} to apply to all
7543     *            packages.
7544     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7545     *            to all users.
7546     * @param persistable If persistable grants should be removed.
7547     */
7548    private void removeUriPermissionsForPackageLocked(
7549            String packageName, int userHandle, boolean persistable) {
7550        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7551            throw new IllegalArgumentException("Must narrow by either package or user");
7552        }
7553
7554        boolean persistChanged = false;
7555
7556        int N = mGrantedUriPermissions.size();
7557        for (int i = 0; i < N; i++) {
7558            final int targetUid = mGrantedUriPermissions.keyAt(i);
7559            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7560
7561            // Only inspect grants matching user
7562            if (userHandle == UserHandle.USER_ALL
7563                    || userHandle == UserHandle.getUserId(targetUid)) {
7564                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7565                    final UriPermission perm = it.next();
7566
7567                    // Only inspect grants matching package
7568                    if (packageName == null || perm.sourcePkg.equals(packageName)
7569                            || perm.targetPkg.equals(packageName)) {
7570                        persistChanged |= perm.revokeModes(persistable
7571                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7572
7573                        // Only remove when no modes remain; any persisted grants
7574                        // will keep this alive.
7575                        if (perm.modeFlags == 0) {
7576                            it.remove();
7577                        }
7578                    }
7579                }
7580
7581                if (perms.isEmpty()) {
7582                    mGrantedUriPermissions.remove(targetUid);
7583                    N--;
7584                    i--;
7585                }
7586            }
7587        }
7588
7589        if (persistChanged) {
7590            schedulePersistUriGrants();
7591        }
7592    }
7593
7594    @Override
7595    public IBinder newUriPermissionOwner(String name) {
7596        enforceNotIsolatedCaller("newUriPermissionOwner");
7597        synchronized(this) {
7598            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7599            return owner.getExternalTokenLocked();
7600        }
7601    }
7602
7603    /**
7604     * @param uri This uri must NOT contain an embedded userId.
7605     * @param sourceUserId The userId in which the uri is to be resolved.
7606     * @param targetUserId The userId of the app that receives the grant.
7607     */
7608    @Override
7609    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7610            final int modeFlags, int sourceUserId, int targetUserId) {
7611        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7612                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7613        synchronized(this) {
7614            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7615            if (owner == null) {
7616                throw new IllegalArgumentException("Unknown owner: " + token);
7617            }
7618            if (fromUid != Binder.getCallingUid()) {
7619                if (Binder.getCallingUid() != Process.myUid()) {
7620                    // Only system code can grant URI permissions on behalf
7621                    // of other users.
7622                    throw new SecurityException("nice try");
7623                }
7624            }
7625            if (targetPkg == null) {
7626                throw new IllegalArgumentException("null target");
7627            }
7628            if (uri == null) {
7629                throw new IllegalArgumentException("null uri");
7630            }
7631
7632            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7633                    modeFlags, owner, targetUserId);
7634        }
7635    }
7636
7637    /**
7638     * @param uri This uri must NOT contain an embedded userId.
7639     * @param userId The userId in which the uri is to be resolved.
7640     */
7641    @Override
7642    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7643        synchronized(this) {
7644            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7645            if (owner == null) {
7646                throw new IllegalArgumentException("Unknown owner: " + token);
7647            }
7648
7649            if (uri == null) {
7650                owner.removeUriPermissionsLocked(mode);
7651            } else {
7652                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7653            }
7654        }
7655    }
7656
7657    private void schedulePersistUriGrants() {
7658        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7659            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7660                    10 * DateUtils.SECOND_IN_MILLIS);
7661        }
7662    }
7663
7664    private void writeGrantedUriPermissions() {
7665        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7666
7667        // Snapshot permissions so we can persist without lock
7668        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7669        synchronized (this) {
7670            final int size = mGrantedUriPermissions.size();
7671            for (int i = 0; i < size; i++) {
7672                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7673                for (UriPermission perm : perms.values()) {
7674                    if (perm.persistedModeFlags != 0) {
7675                        persist.add(perm.snapshot());
7676                    }
7677                }
7678            }
7679        }
7680
7681        FileOutputStream fos = null;
7682        try {
7683            fos = mGrantFile.startWrite();
7684
7685            XmlSerializer out = new FastXmlSerializer();
7686            out.setOutput(fos, "utf-8");
7687            out.startDocument(null, true);
7688            out.startTag(null, TAG_URI_GRANTS);
7689            for (UriPermission.Snapshot perm : persist) {
7690                out.startTag(null, TAG_URI_GRANT);
7691                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7692                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7693                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7694                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7695                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7696                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7697                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7698                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7699                out.endTag(null, TAG_URI_GRANT);
7700            }
7701            out.endTag(null, TAG_URI_GRANTS);
7702            out.endDocument();
7703
7704            mGrantFile.finishWrite(fos);
7705        } catch (IOException e) {
7706            if (fos != null) {
7707                mGrantFile.failWrite(fos);
7708            }
7709        }
7710    }
7711
7712    private void readGrantedUriPermissionsLocked() {
7713        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7714
7715        final long now = System.currentTimeMillis();
7716
7717        FileInputStream fis = null;
7718        try {
7719            fis = mGrantFile.openRead();
7720            final XmlPullParser in = Xml.newPullParser();
7721            in.setInput(fis, null);
7722
7723            int type;
7724            while ((type = in.next()) != END_DOCUMENT) {
7725                final String tag = in.getName();
7726                if (type == START_TAG) {
7727                    if (TAG_URI_GRANT.equals(tag)) {
7728                        final int sourceUserId;
7729                        final int targetUserId;
7730                        final int userHandle = readIntAttribute(in,
7731                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7732                        if (userHandle != UserHandle.USER_NULL) {
7733                            // For backwards compatibility.
7734                            sourceUserId = userHandle;
7735                            targetUserId = userHandle;
7736                        } else {
7737                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7738                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7739                        }
7740                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7741                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7742                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7743                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7744                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7745                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7746
7747                        // Sanity check that provider still belongs to source package
7748                        final ProviderInfo pi = getProviderInfoLocked(
7749                                uri.getAuthority(), sourceUserId);
7750                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7751                            int targetUid = -1;
7752                            try {
7753                                targetUid = AppGlobals.getPackageManager()
7754                                        .getPackageUid(targetPkg, targetUserId);
7755                            } catch (RemoteException e) {
7756                            }
7757                            if (targetUid != -1) {
7758                                final UriPermission perm = findOrCreateUriPermissionLocked(
7759                                        sourcePkg, targetPkg, targetUid,
7760                                        new GrantUri(sourceUserId, uri, prefix));
7761                                perm.initPersistedModes(modeFlags, createdTime);
7762                            }
7763                        } else {
7764                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7765                                    + " but instead found " + pi);
7766                        }
7767                    }
7768                }
7769            }
7770        } catch (FileNotFoundException e) {
7771            // Missing grants is okay
7772        } catch (IOException e) {
7773            Slog.wtf(TAG, "Failed reading Uri grants", e);
7774        } catch (XmlPullParserException e) {
7775            Slog.wtf(TAG, "Failed reading Uri grants", e);
7776        } finally {
7777            IoUtils.closeQuietly(fis);
7778        }
7779    }
7780
7781    /**
7782     * @param uri This uri must NOT contain an embedded userId.
7783     * @param userId The userId in which the uri is to be resolved.
7784     */
7785    @Override
7786    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7787        enforceNotIsolatedCaller("takePersistableUriPermission");
7788
7789        Preconditions.checkFlagsArgument(modeFlags,
7790                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7791
7792        synchronized (this) {
7793            final int callingUid = Binder.getCallingUid();
7794            boolean persistChanged = false;
7795            GrantUri grantUri = new GrantUri(userId, uri, false);
7796
7797            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7798                    new GrantUri(userId, uri, false));
7799            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7800                    new GrantUri(userId, uri, true));
7801
7802            final boolean exactValid = (exactPerm != null)
7803                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7804            final boolean prefixValid = (prefixPerm != null)
7805                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7806
7807            if (!(exactValid || prefixValid)) {
7808                throw new SecurityException("No persistable permission grants found for UID "
7809                        + callingUid + " and Uri " + grantUri.toSafeString());
7810            }
7811
7812            if (exactValid) {
7813                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7814            }
7815            if (prefixValid) {
7816                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7817            }
7818
7819            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7820
7821            if (persistChanged) {
7822                schedulePersistUriGrants();
7823            }
7824        }
7825    }
7826
7827    /**
7828     * @param uri This uri must NOT contain an embedded userId.
7829     * @param userId The userId in which the uri is to be resolved.
7830     */
7831    @Override
7832    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7833        enforceNotIsolatedCaller("releasePersistableUriPermission");
7834
7835        Preconditions.checkFlagsArgument(modeFlags,
7836                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7837
7838        synchronized (this) {
7839            final int callingUid = Binder.getCallingUid();
7840            boolean persistChanged = false;
7841
7842            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7843                    new GrantUri(userId, uri, false));
7844            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7845                    new GrantUri(userId, uri, true));
7846            if (exactPerm == null && prefixPerm == null) {
7847                throw new SecurityException("No permission grants found for UID " + callingUid
7848                        + " and Uri " + uri.toSafeString());
7849            }
7850
7851            if (exactPerm != null) {
7852                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7853                removeUriPermissionIfNeededLocked(exactPerm);
7854            }
7855            if (prefixPerm != null) {
7856                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7857                removeUriPermissionIfNeededLocked(prefixPerm);
7858            }
7859
7860            if (persistChanged) {
7861                schedulePersistUriGrants();
7862            }
7863        }
7864    }
7865
7866    /**
7867     * Prune any older {@link UriPermission} for the given UID until outstanding
7868     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7869     *
7870     * @return if any mutations occured that require persisting.
7871     */
7872    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7873        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7874        if (perms == null) return false;
7875        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7876
7877        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7878        for (UriPermission perm : perms.values()) {
7879            if (perm.persistedModeFlags != 0) {
7880                persisted.add(perm);
7881            }
7882        }
7883
7884        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7885        if (trimCount <= 0) return false;
7886
7887        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7888        for (int i = 0; i < trimCount; i++) {
7889            final UriPermission perm = persisted.get(i);
7890
7891            if (DEBUG_URI_PERMISSION) {
7892                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7893            }
7894
7895            perm.releasePersistableModes(~0);
7896            removeUriPermissionIfNeededLocked(perm);
7897        }
7898
7899        return true;
7900    }
7901
7902    @Override
7903    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7904            String packageName, boolean incoming) {
7905        enforceNotIsolatedCaller("getPersistedUriPermissions");
7906        Preconditions.checkNotNull(packageName, "packageName");
7907
7908        final int callingUid = Binder.getCallingUid();
7909        final IPackageManager pm = AppGlobals.getPackageManager();
7910        try {
7911            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7912            if (packageUid != callingUid) {
7913                throw new SecurityException(
7914                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7915            }
7916        } catch (RemoteException e) {
7917            throw new SecurityException("Failed to verify package name ownership");
7918        }
7919
7920        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7921        synchronized (this) {
7922            if (incoming) {
7923                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7924                        callingUid);
7925                if (perms == null) {
7926                    Slog.w(TAG, "No permission grants found for " + packageName);
7927                } else {
7928                    for (UriPermission perm : perms.values()) {
7929                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7930                            result.add(perm.buildPersistedPublicApiObject());
7931                        }
7932                    }
7933                }
7934            } else {
7935                final int size = mGrantedUriPermissions.size();
7936                for (int i = 0; i < size; i++) {
7937                    final ArrayMap<GrantUri, UriPermission> perms =
7938                            mGrantedUriPermissions.valueAt(i);
7939                    for (UriPermission perm : perms.values()) {
7940                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7941                            result.add(perm.buildPersistedPublicApiObject());
7942                        }
7943                    }
7944                }
7945            }
7946        }
7947        return new ParceledListSlice<android.content.UriPermission>(result);
7948    }
7949
7950    @Override
7951    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7952        synchronized (this) {
7953            ProcessRecord app =
7954                who != null ? getRecordForAppLocked(who) : null;
7955            if (app == null) return;
7956
7957            Message msg = Message.obtain();
7958            msg.what = WAIT_FOR_DEBUGGER_MSG;
7959            msg.obj = app;
7960            msg.arg1 = waiting ? 1 : 0;
7961            mHandler.sendMessage(msg);
7962        }
7963    }
7964
7965    @Override
7966    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7967        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7968        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7969        outInfo.availMem = Process.getFreeMemory();
7970        outInfo.totalMem = Process.getTotalMemory();
7971        outInfo.threshold = homeAppMem;
7972        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7973        outInfo.hiddenAppThreshold = cachedAppMem;
7974        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7975                ProcessList.SERVICE_ADJ);
7976        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7977                ProcessList.VISIBLE_APP_ADJ);
7978        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7979                ProcessList.FOREGROUND_APP_ADJ);
7980    }
7981
7982    // =========================================================
7983    // TASK MANAGEMENT
7984    // =========================================================
7985
7986    @Override
7987    public List<IAppTask> getAppTasks(String callingPackage) {
7988        int callingUid = Binder.getCallingUid();
7989        long ident = Binder.clearCallingIdentity();
7990
7991        synchronized(this) {
7992            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7993            try {
7994                if (localLOGV) Slog.v(TAG, "getAppTasks");
7995
7996                final int N = mRecentTasks.size();
7997                for (int i = 0; i < N; i++) {
7998                    TaskRecord tr = mRecentTasks.get(i);
7999                    // Skip tasks that do not match the caller.  We don't need to verify
8000                    // callingPackage, because we are also limiting to callingUid and know
8001                    // that will limit to the correct security sandbox.
8002                    if (tr.effectiveUid != callingUid) {
8003                        continue;
8004                    }
8005                    Intent intent = tr.getBaseIntent();
8006                    if (intent == null ||
8007                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8008                        continue;
8009                    }
8010                    ActivityManager.RecentTaskInfo taskInfo =
8011                            createRecentTaskInfoFromTaskRecord(tr);
8012                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8013                    list.add(taskImpl);
8014                }
8015            } finally {
8016                Binder.restoreCallingIdentity(ident);
8017            }
8018            return list;
8019        }
8020    }
8021
8022    @Override
8023    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8024        final int callingUid = Binder.getCallingUid();
8025        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8026
8027        synchronized(this) {
8028            if (localLOGV) Slog.v(
8029                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8030
8031            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8032                    callingUid);
8033
8034            // TODO: Improve with MRU list from all ActivityStacks.
8035            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8036        }
8037
8038        return list;
8039    }
8040
8041    TaskRecord getMostRecentTask() {
8042        return mRecentTasks.get(0);
8043    }
8044
8045    /**
8046     * Creates a new RecentTaskInfo from a TaskRecord.
8047     */
8048    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8049        // Update the task description to reflect any changes in the task stack
8050        tr.updateTaskDescription();
8051
8052        // Compose the recent task info
8053        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8054        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8055        rti.persistentId = tr.taskId;
8056        rti.baseIntent = new Intent(tr.getBaseIntent());
8057        rti.origActivity = tr.origActivity;
8058        rti.description = tr.lastDescription;
8059        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8060        rti.userId = tr.userId;
8061        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8062        rti.firstActiveTime = tr.firstActiveTime;
8063        rti.lastActiveTime = tr.lastActiveTime;
8064        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8065        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8066        return rti;
8067    }
8068
8069    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8070        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8071                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8072        if (!allowed) {
8073            if (checkPermission(android.Manifest.permission.GET_TASKS,
8074                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8075                // Temporary compatibility: some existing apps on the system image may
8076                // still be requesting the old permission and not switched to the new
8077                // one; if so, we'll still allow them full access.  This means we need
8078                // to see if they are holding the old permission and are a system app.
8079                try {
8080                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8081                        allowed = true;
8082                        Slog.w(TAG, caller + ": caller " + callingUid
8083                                + " is using old GET_TASKS but privileged; allowing");
8084                    }
8085                } catch (RemoteException e) {
8086                }
8087            }
8088        }
8089        if (!allowed) {
8090            Slog.w(TAG, caller + ": caller " + callingUid
8091                    + " does not hold GET_TASKS; limiting output");
8092        }
8093        return allowed;
8094    }
8095
8096    @Override
8097    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8098        final int callingUid = Binder.getCallingUid();
8099        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8100                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8101
8102        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8103        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8104        synchronized (this) {
8105            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8106                    callingUid);
8107            final boolean detailed = checkCallingPermission(
8108                    android.Manifest.permission.GET_DETAILED_TASKS)
8109                    == PackageManager.PERMISSION_GRANTED;
8110
8111            final int N = mRecentTasks.size();
8112            ArrayList<ActivityManager.RecentTaskInfo> res
8113                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8114                            maxNum < N ? maxNum : N);
8115
8116            final Set<Integer> includedUsers;
8117            if (includeProfiles) {
8118                includedUsers = getProfileIdsLocked(userId);
8119            } else {
8120                includedUsers = new HashSet<Integer>();
8121            }
8122            includedUsers.add(Integer.valueOf(userId));
8123
8124            for (int i=0; i<N && maxNum > 0; i++) {
8125                TaskRecord tr = mRecentTasks.get(i);
8126                // Only add calling user or related users recent tasks
8127                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8128                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8129                    continue;
8130                }
8131
8132                // Return the entry if desired by the caller.  We always return
8133                // the first entry, because callers always expect this to be the
8134                // foreground app.  We may filter others if the caller has
8135                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8136                // we should exclude the entry.
8137
8138                if (i == 0
8139                        || withExcluded
8140                        || (tr.intent == null)
8141                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8142                                == 0)) {
8143                    if (!allowed) {
8144                        // If the caller doesn't have the GET_TASKS permission, then only
8145                        // allow them to see a small subset of tasks -- their own and home.
8146                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8147                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8148                            continue;
8149                        }
8150                    }
8151                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8152                        if (tr.stack != null && tr.stack.isHomeStack()) {
8153                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8154                            continue;
8155                        }
8156                    }
8157                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8158                        // Don't include auto remove tasks that are finished or finishing.
8159                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8160                                + tr);
8161                        continue;
8162                    }
8163                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8164                            && !tr.isAvailable) {
8165                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8166                        continue;
8167                    }
8168
8169                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8170                    if (!detailed) {
8171                        rti.baseIntent.replaceExtras((Bundle)null);
8172                    }
8173
8174                    res.add(rti);
8175                    maxNum--;
8176                }
8177            }
8178            return res;
8179        }
8180    }
8181
8182    private TaskRecord taskForIdLocked(int id) {
8183        final TaskRecord task = recentTaskForIdLocked(id);
8184        if (task != null) {
8185            return task;
8186        }
8187
8188        // Don't give up. Sometimes it just hasn't made it to recents yet.
8189        return mStackSupervisor.anyTaskForIdLocked(id);
8190    }
8191
8192    private TaskRecord recentTaskForIdLocked(int id) {
8193        final int N = mRecentTasks.size();
8194            for (int i=0; i<N; i++) {
8195                TaskRecord tr = mRecentTasks.get(i);
8196                if (tr.taskId == id) {
8197                    return tr;
8198                }
8199            }
8200            return null;
8201    }
8202
8203    @Override
8204    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8205        synchronized (this) {
8206            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8207                    "getTaskThumbnail()");
8208            TaskRecord tr = recentTaskForIdLocked(id);
8209            if (tr != null) {
8210                return tr.getTaskThumbnailLocked();
8211            }
8212        }
8213        return null;
8214    }
8215
8216    @Override
8217    public int addAppTask(IBinder activityToken, Intent intent,
8218            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8219        final int callingUid = Binder.getCallingUid();
8220        final long callingIdent = Binder.clearCallingIdentity();
8221
8222        try {
8223            synchronized (this) {
8224                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8225                if (r == null) {
8226                    throw new IllegalArgumentException("Activity does not exist; token="
8227                            + activityToken);
8228                }
8229                ComponentName comp = intent.getComponent();
8230                if (comp == null) {
8231                    throw new IllegalArgumentException("Intent " + intent
8232                            + " must specify explicit component");
8233                }
8234                if (thumbnail.getWidth() != mThumbnailWidth
8235                        || thumbnail.getHeight() != mThumbnailHeight) {
8236                    throw new IllegalArgumentException("Bad thumbnail size: got "
8237                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8238                            + mThumbnailWidth + "x" + mThumbnailHeight);
8239                }
8240                if (intent.getSelector() != null) {
8241                    intent.setSelector(null);
8242                }
8243                if (intent.getSourceBounds() != null) {
8244                    intent.setSourceBounds(null);
8245                }
8246                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8247                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8248                        // The caller has added this as an auto-remove task...  that makes no
8249                        // sense, so turn off auto-remove.
8250                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8251                    }
8252                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8253                    // Must be a new task.
8254                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8255                }
8256                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8257                    mLastAddedTaskActivity = null;
8258                }
8259                ActivityInfo ainfo = mLastAddedTaskActivity;
8260                if (ainfo == null) {
8261                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8262                            comp, 0, UserHandle.getUserId(callingUid));
8263                    if (ainfo.applicationInfo.uid != callingUid) {
8264                        throw new SecurityException(
8265                                "Can't add task for another application: target uid="
8266                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8267                    }
8268                }
8269
8270                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8271                        intent, description);
8272
8273                int trimIdx = trimRecentsForTask(task, false);
8274                if (trimIdx >= 0) {
8275                    // If this would have caused a trim, then we'll abort because that
8276                    // means it would be added at the end of the list but then just removed.
8277                    return -1;
8278                }
8279
8280                final int N = mRecentTasks.size();
8281                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8282                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8283                    tr.removedFromRecents(mTaskPersister);
8284                }
8285
8286                task.inRecents = true;
8287                mRecentTasks.add(task);
8288                r.task.stack.addTask(task, false, false);
8289
8290                task.setLastThumbnail(thumbnail);
8291                task.freeLastThumbnail();
8292
8293                return task.taskId;
8294            }
8295        } finally {
8296            Binder.restoreCallingIdentity(callingIdent);
8297        }
8298    }
8299
8300    @Override
8301    public Point getAppTaskThumbnailSize() {
8302        synchronized (this) {
8303            return new Point(mThumbnailWidth,  mThumbnailHeight);
8304        }
8305    }
8306
8307    @Override
8308    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8309        synchronized (this) {
8310            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8311            if (r != null) {
8312                r.setTaskDescription(td);
8313                r.task.updateTaskDescription();
8314            }
8315        }
8316    }
8317
8318    @Override
8319    public Bitmap getTaskDescriptionIcon(String filename) {
8320        if (!FileUtils.isValidExtFilename(filename)
8321                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8322            throw new IllegalArgumentException("Bad filename: " + filename);
8323        }
8324        return mTaskPersister.getTaskDescriptionIcon(filename);
8325    }
8326
8327    @Override
8328    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8329            throws RemoteException {
8330        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8331                opts.getCustomInPlaceResId() == 0) {
8332            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8333                    "with valid animation");
8334        }
8335        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8336        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8337                opts.getCustomInPlaceResId());
8338        mWindowManager.executeAppTransition();
8339    }
8340
8341    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8342        mRecentTasks.remove(tr);
8343        tr.removedFromRecents(mTaskPersister);
8344        ComponentName component = tr.getBaseIntent().getComponent();
8345        if (component == null) {
8346            Slog.w(TAG, "No component for base intent of task: " + tr);
8347            return;
8348        }
8349
8350        if (!killProcess) {
8351            return;
8352        }
8353
8354        // Determine if the process(es) for this task should be killed.
8355        final String pkg = component.getPackageName();
8356        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8357        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8358        for (int i = 0; i < pmap.size(); i++) {
8359
8360            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8361            for (int j = 0; j < uids.size(); j++) {
8362                ProcessRecord proc = uids.valueAt(j);
8363                if (proc.userId != tr.userId) {
8364                    // Don't kill process for a different user.
8365                    continue;
8366                }
8367                if (proc == mHomeProcess) {
8368                    // Don't kill the home process along with tasks from the same package.
8369                    continue;
8370                }
8371                if (!proc.pkgList.containsKey(pkg)) {
8372                    // Don't kill process that is not associated with this task.
8373                    continue;
8374                }
8375
8376                for (int k = 0; k < proc.activities.size(); k++) {
8377                    TaskRecord otherTask = proc.activities.get(k).task;
8378                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8379                        // Don't kill process(es) that has an activity in a different task that is
8380                        // also in recents.
8381                        return;
8382                    }
8383                }
8384
8385                // Add process to kill list.
8386                procsToKill.add(proc);
8387            }
8388        }
8389
8390        // Find any running services associated with this app and stop if needed.
8391        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8392
8393        // Kill the running processes.
8394        for (int i = 0; i < procsToKill.size(); i++) {
8395            ProcessRecord pr = procsToKill.get(i);
8396            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8397                pr.kill("remove task", true);
8398            } else {
8399                pr.waitingToKill = "remove task";
8400            }
8401        }
8402    }
8403
8404    /**
8405     * Removes the task with the specified task id.
8406     *
8407     * @param taskId Identifier of the task to be removed.
8408     * @param killProcess Kill any process associated with the task if possible.
8409     * @return Returns true if the given task was found and removed.
8410     */
8411    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8412        TaskRecord tr = taskForIdLocked(taskId);
8413        if (tr != null) {
8414            tr.removeTaskActivitiesLocked();
8415            cleanUpRemovedTaskLocked(tr, killProcess);
8416            if (tr.isPersistable) {
8417                notifyTaskPersisterLocked(null, true);
8418            }
8419            return true;
8420        }
8421        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8422        return false;
8423    }
8424
8425    @Override
8426    public boolean removeTask(int taskId) {
8427        synchronized (this) {
8428            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8429                    "removeTask()");
8430            long ident = Binder.clearCallingIdentity();
8431            try {
8432                return removeTaskByIdLocked(taskId, true);
8433            } finally {
8434                Binder.restoreCallingIdentity(ident);
8435            }
8436        }
8437    }
8438
8439    /**
8440     * TODO: Add mController hook
8441     */
8442    @Override
8443    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8444        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8445                "moveTaskToFront()");
8446
8447        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8448        synchronized(this) {
8449            moveTaskToFrontLocked(taskId, flags, options);
8450        }
8451    }
8452
8453    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8454        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8455                Binder.getCallingUid(), -1, -1, "Task to front")) {
8456            ActivityOptions.abort(options);
8457            return;
8458        }
8459        final long origId = Binder.clearCallingIdentity();
8460        try {
8461            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8462            if (task == null) {
8463                Slog.d(TAG, "Could not find task for id: "+ taskId);
8464                return;
8465            }
8466            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8467                mStackSupervisor.showLockTaskToast();
8468                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8469                return;
8470            }
8471            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8472            if (prev != null && prev.isRecentsActivity()) {
8473                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8474            }
8475            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8476        } finally {
8477            Binder.restoreCallingIdentity(origId);
8478        }
8479        ActivityOptions.abort(options);
8480    }
8481
8482    @Override
8483    public void moveTaskToBack(int taskId) {
8484        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8485                "moveTaskToBack()");
8486
8487        synchronized(this) {
8488            TaskRecord tr = taskForIdLocked(taskId);
8489            if (tr != null) {
8490                if (tr == mStackSupervisor.mLockTaskModeTask) {
8491                    mStackSupervisor.showLockTaskToast();
8492                    return;
8493                }
8494                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8495                ActivityStack stack = tr.stack;
8496                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8497                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8498                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8499                        return;
8500                    }
8501                }
8502                final long origId = Binder.clearCallingIdentity();
8503                try {
8504                    stack.moveTaskToBackLocked(taskId, null);
8505                } finally {
8506                    Binder.restoreCallingIdentity(origId);
8507                }
8508            }
8509        }
8510    }
8511
8512    /**
8513     * Moves an activity, and all of the other activities within the same task, to the bottom
8514     * of the history stack.  The activity's order within the task is unchanged.
8515     *
8516     * @param token A reference to the activity we wish to move
8517     * @param nonRoot If false then this only works if the activity is the root
8518     *                of a task; if true it will work for any activity in a task.
8519     * @return Returns true if the move completed, false if not.
8520     */
8521    @Override
8522    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8523        enforceNotIsolatedCaller("moveActivityTaskToBack");
8524        synchronized(this) {
8525            final long origId = Binder.clearCallingIdentity();
8526            try {
8527                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8528                if (taskId >= 0) {
8529                    if ((mStackSupervisor.mLockTaskModeTask != null)
8530                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8531                        mStackSupervisor.showLockTaskToast();
8532                        return false;
8533                    }
8534                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8535                }
8536            } finally {
8537                Binder.restoreCallingIdentity(origId);
8538            }
8539        }
8540        return false;
8541    }
8542
8543    @Override
8544    public void moveTaskBackwards(int task) {
8545        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8546                "moveTaskBackwards()");
8547
8548        synchronized(this) {
8549            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8550                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8551                return;
8552            }
8553            final long origId = Binder.clearCallingIdentity();
8554            moveTaskBackwardsLocked(task);
8555            Binder.restoreCallingIdentity(origId);
8556        }
8557    }
8558
8559    private final void moveTaskBackwardsLocked(int task) {
8560        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8561    }
8562
8563    @Override
8564    public IBinder getHomeActivityToken() throws RemoteException {
8565        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8566                "getHomeActivityToken()");
8567        synchronized (this) {
8568            return mStackSupervisor.getHomeActivityToken();
8569        }
8570    }
8571
8572    @Override
8573    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8574            IActivityContainerCallback callback) throws RemoteException {
8575        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8576                "createActivityContainer()");
8577        synchronized (this) {
8578            if (parentActivityToken == null) {
8579                throw new IllegalArgumentException("parent token must not be null");
8580            }
8581            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8582            if (r == null) {
8583                return null;
8584            }
8585            if (callback == null) {
8586                throw new IllegalArgumentException("callback must not be null");
8587            }
8588            return mStackSupervisor.createActivityContainer(r, callback);
8589        }
8590    }
8591
8592    @Override
8593    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8594        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8595                "deleteActivityContainer()");
8596        synchronized (this) {
8597            mStackSupervisor.deleteActivityContainer(container);
8598        }
8599    }
8600
8601    @Override
8602    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8603            throws RemoteException {
8604        synchronized (this) {
8605            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8606            if (stack != null) {
8607                return stack.mActivityContainer;
8608            }
8609            return null;
8610        }
8611    }
8612
8613    @Override
8614    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8615        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8616                "moveTaskToStack()");
8617        if (stackId == HOME_STACK_ID) {
8618            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8619                    new RuntimeException("here").fillInStackTrace());
8620        }
8621        synchronized (this) {
8622            long ident = Binder.clearCallingIdentity();
8623            try {
8624                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8625                        + stackId + " toTop=" + toTop);
8626                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8627            } finally {
8628                Binder.restoreCallingIdentity(ident);
8629            }
8630        }
8631    }
8632
8633    @Override
8634    public void resizeStack(int stackBoxId, Rect bounds) {
8635        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8636                "resizeStackBox()");
8637        long ident = Binder.clearCallingIdentity();
8638        try {
8639            mWindowManager.resizeStack(stackBoxId, bounds);
8640        } finally {
8641            Binder.restoreCallingIdentity(ident);
8642        }
8643    }
8644
8645    @Override
8646    public List<StackInfo> getAllStackInfos() {
8647        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8648                "getAllStackInfos()");
8649        long ident = Binder.clearCallingIdentity();
8650        try {
8651            synchronized (this) {
8652                return mStackSupervisor.getAllStackInfosLocked();
8653            }
8654        } finally {
8655            Binder.restoreCallingIdentity(ident);
8656        }
8657    }
8658
8659    @Override
8660    public StackInfo getStackInfo(int stackId) {
8661        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8662                "getStackInfo()");
8663        long ident = Binder.clearCallingIdentity();
8664        try {
8665            synchronized (this) {
8666                return mStackSupervisor.getStackInfoLocked(stackId);
8667            }
8668        } finally {
8669            Binder.restoreCallingIdentity(ident);
8670        }
8671    }
8672
8673    @Override
8674    public boolean isInHomeStack(int taskId) {
8675        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8676                "getStackInfo()");
8677        long ident = Binder.clearCallingIdentity();
8678        try {
8679            synchronized (this) {
8680                TaskRecord tr = taskForIdLocked(taskId);
8681                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8682            }
8683        } finally {
8684            Binder.restoreCallingIdentity(ident);
8685        }
8686    }
8687
8688    @Override
8689    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8690        synchronized(this) {
8691            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8692        }
8693    }
8694
8695    private boolean isLockTaskAuthorized(String pkg) {
8696        final DevicePolicyManager dpm = (DevicePolicyManager)
8697                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8698        try {
8699            int uid = mContext.getPackageManager().getPackageUid(pkg,
8700                    Binder.getCallingUserHandle().getIdentifier());
8701            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8702        } catch (NameNotFoundException e) {
8703            return false;
8704        }
8705    }
8706
8707    void startLockTaskMode(TaskRecord task) {
8708        final String pkg;
8709        synchronized (this) {
8710            pkg = task.intent.getComponent().getPackageName();
8711        }
8712        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8713        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8714            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8715                    StatusBarManagerInternal.class);
8716            if (statusBarManager != null) {
8717                statusBarManager.showScreenPinningRequest();
8718            }
8719            return;
8720        }
8721        long ident = Binder.clearCallingIdentity();
8722        try {
8723            synchronized (this) {
8724                // Since we lost lock on task, make sure it is still there.
8725                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8726                if (task != null) {
8727                    if (!isSystemInitiated
8728                            && ((mStackSupervisor.getFocusedStack() == null)
8729                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8730                        throw new IllegalArgumentException("Invalid task, not in foreground");
8731                    }
8732                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8733                }
8734            }
8735        } finally {
8736            Binder.restoreCallingIdentity(ident);
8737        }
8738    }
8739
8740    @Override
8741    public void startLockTaskMode(int taskId) {
8742        final TaskRecord task;
8743        long ident = Binder.clearCallingIdentity();
8744        try {
8745            synchronized (this) {
8746                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8747            }
8748        } finally {
8749            Binder.restoreCallingIdentity(ident);
8750        }
8751        if (task != null) {
8752            startLockTaskMode(task);
8753        }
8754    }
8755
8756    @Override
8757    public void startLockTaskMode(IBinder token) {
8758        final TaskRecord task;
8759        long ident = Binder.clearCallingIdentity();
8760        try {
8761            synchronized (this) {
8762                final ActivityRecord r = ActivityRecord.forToken(token);
8763                if (r == null) {
8764                    return;
8765                }
8766                task = r.task;
8767            }
8768        } finally {
8769            Binder.restoreCallingIdentity(ident);
8770        }
8771        if (task != null) {
8772            startLockTaskMode(task);
8773        }
8774    }
8775
8776    @Override
8777    public void startLockTaskModeOnCurrent() throws RemoteException {
8778        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8779                "startLockTaskModeOnCurrent");
8780        long ident = Binder.clearCallingIdentity();
8781        try {
8782            ActivityRecord r = null;
8783            synchronized (this) {
8784                r = mStackSupervisor.topRunningActivityLocked();
8785            }
8786            startLockTaskMode(r.task);
8787        } finally {
8788            Binder.restoreCallingIdentity(ident);
8789        }
8790    }
8791
8792    @Override
8793    public void stopLockTaskMode() {
8794        // Verify that the user matches the package of the intent for the TaskRecord
8795        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8796        // and stopLockTaskMode.
8797        final int callingUid = Binder.getCallingUid();
8798        if (callingUid != Process.SYSTEM_UID) {
8799            try {
8800                String pkg =
8801                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8802                int uid = mContext.getPackageManager().getPackageUid(pkg,
8803                        Binder.getCallingUserHandle().getIdentifier());
8804                if (uid != callingUid) {
8805                    throw new SecurityException("Invalid uid, expected " + uid);
8806                }
8807            } catch (NameNotFoundException e) {
8808                Log.d(TAG, "stopLockTaskMode " + e);
8809                return;
8810            }
8811        }
8812        long ident = Binder.clearCallingIdentity();
8813        try {
8814            Log.d(TAG, "stopLockTaskMode");
8815            // Stop lock task
8816            synchronized (this) {
8817                mStackSupervisor.setLockTaskModeLocked(null, false);
8818            }
8819        } finally {
8820            Binder.restoreCallingIdentity(ident);
8821        }
8822    }
8823
8824    @Override
8825    public void stopLockTaskModeOnCurrent() throws RemoteException {
8826        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8827                "stopLockTaskModeOnCurrent");
8828        long ident = Binder.clearCallingIdentity();
8829        try {
8830            stopLockTaskMode();
8831        } finally {
8832            Binder.restoreCallingIdentity(ident);
8833        }
8834    }
8835
8836    @Override
8837    public boolean isInLockTaskMode() {
8838        synchronized (this) {
8839            return mStackSupervisor.isInLockTaskMode();
8840        }
8841    }
8842
8843    // =========================================================
8844    // CONTENT PROVIDERS
8845    // =========================================================
8846
8847    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8848        List<ProviderInfo> providers = null;
8849        try {
8850            providers = AppGlobals.getPackageManager().
8851                queryContentProviders(app.processName, app.uid,
8852                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8853        } catch (RemoteException ex) {
8854        }
8855        if (DEBUG_MU)
8856            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8857        int userId = app.userId;
8858        if (providers != null) {
8859            int N = providers.size();
8860            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8861            for (int i=0; i<N; i++) {
8862                ProviderInfo cpi =
8863                    (ProviderInfo)providers.get(i);
8864                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8865                        cpi.name, cpi.flags);
8866                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8867                    // This is a singleton provider, but a user besides the
8868                    // default user is asking to initialize a process it runs
8869                    // in...  well, no, it doesn't actually run in this process,
8870                    // it runs in the process of the default user.  Get rid of it.
8871                    providers.remove(i);
8872                    N--;
8873                    i--;
8874                    continue;
8875                }
8876
8877                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8878                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8879                if (cpr == null) {
8880                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8881                    mProviderMap.putProviderByClass(comp, cpr);
8882                }
8883                if (DEBUG_MU)
8884                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8885                app.pubProviders.put(cpi.name, cpr);
8886                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8887                    // Don't add this if it is a platform component that is marked
8888                    // to run in multiple processes, because this is actually
8889                    // part of the framework so doesn't make sense to track as a
8890                    // separate apk in the process.
8891                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8892                            mProcessStats);
8893                }
8894                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8895            }
8896        }
8897        return providers;
8898    }
8899
8900    /**
8901     * Check if {@link ProcessRecord} has a possible chance at accessing the
8902     * given {@link ProviderInfo}. Final permission checking is always done
8903     * in {@link ContentProvider}.
8904     */
8905    private final String checkContentProviderPermissionLocked(
8906            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8907        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8908        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8909        boolean checkedGrants = false;
8910        if (checkUser) {
8911            // Looking for cross-user grants before enforcing the typical cross-users permissions
8912            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8913            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8914                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8915                    return null;
8916                }
8917                checkedGrants = true;
8918            }
8919            userId = handleIncomingUser(callingPid, callingUid, userId,
8920                    false, ALLOW_NON_FULL,
8921                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8922            if (userId != tmpTargetUserId) {
8923                // When we actually went to determine the final targer user ID, this ended
8924                // up different than our initial check for the authority.  This is because
8925                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8926                // SELF.  So we need to re-check the grants again.
8927                checkedGrants = false;
8928            }
8929        }
8930        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8931                cpi.applicationInfo.uid, cpi.exported)
8932                == PackageManager.PERMISSION_GRANTED) {
8933            return null;
8934        }
8935        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8936                cpi.applicationInfo.uid, cpi.exported)
8937                == PackageManager.PERMISSION_GRANTED) {
8938            return null;
8939        }
8940
8941        PathPermission[] pps = cpi.pathPermissions;
8942        if (pps != null) {
8943            int i = pps.length;
8944            while (i > 0) {
8945                i--;
8946                PathPermission pp = pps[i];
8947                String pprperm = pp.getReadPermission();
8948                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8949                        cpi.applicationInfo.uid, cpi.exported)
8950                        == PackageManager.PERMISSION_GRANTED) {
8951                    return null;
8952                }
8953                String ppwperm = pp.getWritePermission();
8954                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8955                        cpi.applicationInfo.uid, cpi.exported)
8956                        == PackageManager.PERMISSION_GRANTED) {
8957                    return null;
8958                }
8959            }
8960        }
8961        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8962            return null;
8963        }
8964
8965        String msg;
8966        if (!cpi.exported) {
8967            msg = "Permission Denial: opening provider " + cpi.name
8968                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8969                    + ", uid=" + callingUid + ") that is not exported from uid "
8970                    + cpi.applicationInfo.uid;
8971        } else {
8972            msg = "Permission Denial: opening provider " + cpi.name
8973                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8974                    + ", uid=" + callingUid + ") requires "
8975                    + cpi.readPermission + " or " + cpi.writePermission;
8976        }
8977        Slog.w(TAG, msg);
8978        return msg;
8979    }
8980
8981    /**
8982     * Returns if the ContentProvider has granted a uri to callingUid
8983     */
8984    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8985        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8986        if (perms != null) {
8987            for (int i=perms.size()-1; i>=0; i--) {
8988                GrantUri grantUri = perms.keyAt(i);
8989                if (grantUri.sourceUserId == userId || !checkUser) {
8990                    if (matchesProvider(grantUri.uri, cpi)) {
8991                        return true;
8992                    }
8993                }
8994            }
8995        }
8996        return false;
8997    }
8998
8999    /**
9000     * Returns true if the uri authority is one of the authorities specified in the provider.
9001     */
9002    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9003        String uriAuth = uri.getAuthority();
9004        String cpiAuth = cpi.authority;
9005        if (cpiAuth.indexOf(';') == -1) {
9006            return cpiAuth.equals(uriAuth);
9007        }
9008        String[] cpiAuths = cpiAuth.split(";");
9009        int length = cpiAuths.length;
9010        for (int i = 0; i < length; i++) {
9011            if (cpiAuths[i].equals(uriAuth)) return true;
9012        }
9013        return false;
9014    }
9015
9016    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9017            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9018        if (r != null) {
9019            for (int i=0; i<r.conProviders.size(); i++) {
9020                ContentProviderConnection conn = r.conProviders.get(i);
9021                if (conn.provider == cpr) {
9022                    if (DEBUG_PROVIDER) Slog.v(TAG,
9023                            "Adding provider requested by "
9024                            + r.processName + " from process "
9025                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9026                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9027                    if (stable) {
9028                        conn.stableCount++;
9029                        conn.numStableIncs++;
9030                    } else {
9031                        conn.unstableCount++;
9032                        conn.numUnstableIncs++;
9033                    }
9034                    return conn;
9035                }
9036            }
9037            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9038            if (stable) {
9039                conn.stableCount = 1;
9040                conn.numStableIncs = 1;
9041            } else {
9042                conn.unstableCount = 1;
9043                conn.numUnstableIncs = 1;
9044            }
9045            cpr.connections.add(conn);
9046            r.conProviders.add(conn);
9047            return conn;
9048        }
9049        cpr.addExternalProcessHandleLocked(externalProcessToken);
9050        return null;
9051    }
9052
9053    boolean decProviderCountLocked(ContentProviderConnection conn,
9054            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9055        if (conn != null) {
9056            cpr = conn.provider;
9057            if (DEBUG_PROVIDER) Slog.v(TAG,
9058                    "Removing provider requested by "
9059                    + conn.client.processName + " from process "
9060                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9061                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9062            if (stable) {
9063                conn.stableCount--;
9064            } else {
9065                conn.unstableCount--;
9066            }
9067            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9068                cpr.connections.remove(conn);
9069                conn.client.conProviders.remove(conn);
9070                return true;
9071            }
9072            return false;
9073        }
9074        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9075        return false;
9076    }
9077
9078    private void checkTime(long startTime, String where) {
9079        long now = SystemClock.elapsedRealtime();
9080        if ((now-startTime) > 1000) {
9081            // If we are taking more than a second, log about it.
9082            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9083        }
9084    }
9085
9086    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9087            String name, IBinder token, boolean stable, int userId) {
9088        ContentProviderRecord cpr;
9089        ContentProviderConnection conn = null;
9090        ProviderInfo cpi = null;
9091
9092        synchronized(this) {
9093            long startTime = SystemClock.elapsedRealtime();
9094
9095            ProcessRecord r = null;
9096            if (caller != null) {
9097                r = getRecordForAppLocked(caller);
9098                if (r == null) {
9099                    throw new SecurityException(
9100                            "Unable to find app for caller " + caller
9101                          + " (pid=" + Binder.getCallingPid()
9102                          + ") when getting content provider " + name);
9103                }
9104            }
9105
9106            boolean checkCrossUser = true;
9107
9108            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9109
9110            // First check if this content provider has been published...
9111            cpr = mProviderMap.getProviderByName(name, userId);
9112            // If that didn't work, check if it exists for user 0 and then
9113            // verify that it's a singleton provider before using it.
9114            if (cpr == null && userId != UserHandle.USER_OWNER) {
9115                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9116                if (cpr != null) {
9117                    cpi = cpr.info;
9118                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9119                            cpi.name, cpi.flags)
9120                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9121                        userId = UserHandle.USER_OWNER;
9122                        checkCrossUser = false;
9123                    } else {
9124                        cpr = null;
9125                        cpi = null;
9126                    }
9127                }
9128            }
9129
9130            boolean providerRunning = cpr != null;
9131            if (providerRunning) {
9132                cpi = cpr.info;
9133                String msg;
9134                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9135                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9136                        != null) {
9137                    throw new SecurityException(msg);
9138                }
9139                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9140
9141                if (r != null && cpr.canRunHere(r)) {
9142                    // This provider has been published or is in the process
9143                    // of being published...  but it is also allowed to run
9144                    // in the caller's process, so don't make a connection
9145                    // and just let the caller instantiate its own instance.
9146                    ContentProviderHolder holder = cpr.newHolder(null);
9147                    // don't give caller the provider object, it needs
9148                    // to make its own.
9149                    holder.provider = null;
9150                    return holder;
9151                }
9152
9153                final long origId = Binder.clearCallingIdentity();
9154
9155                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9156
9157                // In this case the provider instance already exists, so we can
9158                // return it right away.
9159                conn = incProviderCountLocked(r, cpr, token, stable);
9160                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9161                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9162                        // If this is a perceptible app accessing the provider,
9163                        // make sure to count it as being accessed and thus
9164                        // back up on the LRU list.  This is good because
9165                        // content providers are often expensive to start.
9166                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9167                        updateLruProcessLocked(cpr.proc, false, null);
9168                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9169                    }
9170                }
9171
9172                if (cpr.proc != null) {
9173                    if (false) {
9174                        if (cpr.name.flattenToShortString().equals(
9175                                "com.android.providers.calendar/.CalendarProvider2")) {
9176                            Slog.v(TAG, "****************** KILLING "
9177                                + cpr.name.flattenToShortString());
9178                            Process.killProcess(cpr.proc.pid);
9179                        }
9180                    }
9181                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9182                    boolean success = updateOomAdjLocked(cpr.proc);
9183                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9184                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9185                    // NOTE: there is still a race here where a signal could be
9186                    // pending on the process even though we managed to update its
9187                    // adj level.  Not sure what to do about this, but at least
9188                    // the race is now smaller.
9189                    if (!success) {
9190                        // Uh oh...  it looks like the provider's process
9191                        // has been killed on us.  We need to wait for a new
9192                        // process to be started, and make sure its death
9193                        // doesn't kill our process.
9194                        Slog.i(TAG,
9195                                "Existing provider " + cpr.name.flattenToShortString()
9196                                + " is crashing; detaching " + r);
9197                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9198                        checkTime(startTime, "getContentProviderImpl: before appDied");
9199                        appDiedLocked(cpr.proc);
9200                        checkTime(startTime, "getContentProviderImpl: after appDied");
9201                        if (!lastRef) {
9202                            // This wasn't the last ref our process had on
9203                            // the provider...  we have now been killed, bail.
9204                            return null;
9205                        }
9206                        providerRunning = false;
9207                        conn = null;
9208                    }
9209                }
9210
9211                Binder.restoreCallingIdentity(origId);
9212            }
9213
9214            boolean singleton;
9215            if (!providerRunning) {
9216                try {
9217                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9218                    cpi = AppGlobals.getPackageManager().
9219                        resolveContentProvider(name,
9220                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9221                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9222                } catch (RemoteException ex) {
9223                }
9224                if (cpi == null) {
9225                    return null;
9226                }
9227                // If the provider is a singleton AND
9228                // (it's a call within the same user || the provider is a
9229                // privileged app)
9230                // Then allow connecting to the singleton provider
9231                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9232                        cpi.name, cpi.flags)
9233                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9234                if (singleton) {
9235                    userId = UserHandle.USER_OWNER;
9236                }
9237                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9238                checkTime(startTime, "getContentProviderImpl: got app info for user");
9239
9240                String msg;
9241                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9242                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9243                        != null) {
9244                    throw new SecurityException(msg);
9245                }
9246                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9247
9248                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9249                        && !cpi.processName.equals("system")) {
9250                    // If this content provider does not run in the system
9251                    // process, and the system is not yet ready to run other
9252                    // processes, then fail fast instead of hanging.
9253                    throw new IllegalArgumentException(
9254                            "Attempt to launch content provider before system ready");
9255                }
9256
9257                // Make sure that the user who owns this provider is started.  If not,
9258                // we don't want to allow it to run.
9259                if (mStartedUsers.get(userId) == null) {
9260                    Slog.w(TAG, "Unable to launch app "
9261                            + cpi.applicationInfo.packageName + "/"
9262                            + cpi.applicationInfo.uid + " for provider "
9263                            + name + ": user " + userId + " is stopped");
9264                    return null;
9265                }
9266
9267                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9268                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9269                cpr = mProviderMap.getProviderByClass(comp, userId);
9270                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9271                final boolean firstClass = cpr == null;
9272                if (firstClass) {
9273                    final long ident = Binder.clearCallingIdentity();
9274                    try {
9275                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9276                        ApplicationInfo ai =
9277                            AppGlobals.getPackageManager().
9278                                getApplicationInfo(
9279                                        cpi.applicationInfo.packageName,
9280                                        STOCK_PM_FLAGS, userId);
9281                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9282                        if (ai == null) {
9283                            Slog.w(TAG, "No package info for content provider "
9284                                    + cpi.name);
9285                            return null;
9286                        }
9287                        ai = getAppInfoForUser(ai, userId);
9288                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9289                    } catch (RemoteException ex) {
9290                        // pm is in same process, this will never happen.
9291                    } finally {
9292                        Binder.restoreCallingIdentity(ident);
9293                    }
9294                }
9295
9296                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9297
9298                if (r != null && cpr.canRunHere(r)) {
9299                    // If this is a multiprocess provider, then just return its
9300                    // info and allow the caller to instantiate it.  Only do
9301                    // this if the provider is the same user as the caller's
9302                    // process, or can run as root (so can be in any process).
9303                    return cpr.newHolder(null);
9304                }
9305
9306                if (DEBUG_PROVIDER) {
9307                    RuntimeException e = new RuntimeException("here");
9308                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9309                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9310                }
9311
9312                // This is single process, and our app is now connecting to it.
9313                // See if we are already in the process of launching this
9314                // provider.
9315                final int N = mLaunchingProviders.size();
9316                int i;
9317                for (i=0; i<N; i++) {
9318                    if (mLaunchingProviders.get(i) == cpr) {
9319                        break;
9320                    }
9321                }
9322
9323                // If the provider is not already being launched, then get it
9324                // started.
9325                if (i >= N) {
9326                    final long origId = Binder.clearCallingIdentity();
9327
9328                    try {
9329                        // Content provider is now in use, its package can't be stopped.
9330                        try {
9331                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9332                            AppGlobals.getPackageManager().setPackageStoppedState(
9333                                    cpr.appInfo.packageName, false, userId);
9334                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9335                        } catch (RemoteException e) {
9336                        } catch (IllegalArgumentException e) {
9337                            Slog.w(TAG, "Failed trying to unstop package "
9338                                    + cpr.appInfo.packageName + ": " + e);
9339                        }
9340
9341                        // Use existing process if already started
9342                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9343                        ProcessRecord proc = getProcessRecordLocked(
9344                                cpi.processName, cpr.appInfo.uid, false);
9345                        if (proc != null && proc.thread != null) {
9346                            if (DEBUG_PROVIDER) {
9347                                Slog.d(TAG, "Installing in existing process " + proc);
9348                            }
9349                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9350                            proc.pubProviders.put(cpi.name, cpr);
9351                            try {
9352                                proc.thread.scheduleInstallProvider(cpi);
9353                            } catch (RemoteException e) {
9354                            }
9355                        } else {
9356                            checkTime(startTime, "getContentProviderImpl: before start process");
9357                            proc = startProcessLocked(cpi.processName,
9358                                    cpr.appInfo, false, 0, "content provider",
9359                                    new ComponentName(cpi.applicationInfo.packageName,
9360                                            cpi.name), false, false, false);
9361                            checkTime(startTime, "getContentProviderImpl: after start process");
9362                            if (proc == null) {
9363                                Slog.w(TAG, "Unable to launch app "
9364                                        + cpi.applicationInfo.packageName + "/"
9365                                        + cpi.applicationInfo.uid + " for provider "
9366                                        + name + ": process is bad");
9367                                return null;
9368                            }
9369                        }
9370                        cpr.launchingApp = proc;
9371                        mLaunchingProviders.add(cpr);
9372                    } finally {
9373                        Binder.restoreCallingIdentity(origId);
9374                    }
9375                }
9376
9377                checkTime(startTime, "getContentProviderImpl: updating data structures");
9378
9379                // Make sure the provider is published (the same provider class
9380                // may be published under multiple names).
9381                if (firstClass) {
9382                    mProviderMap.putProviderByClass(comp, cpr);
9383                }
9384
9385                mProviderMap.putProviderByName(name, cpr);
9386                conn = incProviderCountLocked(r, cpr, token, stable);
9387                if (conn != null) {
9388                    conn.waiting = true;
9389                }
9390            }
9391            checkTime(startTime, "getContentProviderImpl: done!");
9392        }
9393
9394        // Wait for the provider to be published...
9395        synchronized (cpr) {
9396            while (cpr.provider == null) {
9397                if (cpr.launchingApp == null) {
9398                    Slog.w(TAG, "Unable to launch app "
9399                            + cpi.applicationInfo.packageName + "/"
9400                            + cpi.applicationInfo.uid + " for provider "
9401                            + name + ": launching app became null");
9402                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9403                            UserHandle.getUserId(cpi.applicationInfo.uid),
9404                            cpi.applicationInfo.packageName,
9405                            cpi.applicationInfo.uid, name);
9406                    return null;
9407                }
9408                try {
9409                    if (DEBUG_MU) {
9410                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9411                                + cpr.launchingApp);
9412                    }
9413                    if (conn != null) {
9414                        conn.waiting = true;
9415                    }
9416                    cpr.wait();
9417                } catch (InterruptedException ex) {
9418                } finally {
9419                    if (conn != null) {
9420                        conn.waiting = false;
9421                    }
9422                }
9423            }
9424        }
9425        return cpr != null ? cpr.newHolder(conn) : null;
9426    }
9427
9428    @Override
9429    public final ContentProviderHolder getContentProvider(
9430            IApplicationThread caller, String name, int userId, boolean stable) {
9431        enforceNotIsolatedCaller("getContentProvider");
9432        if (caller == null) {
9433            String msg = "null IApplicationThread when getting content provider "
9434                    + name;
9435            Slog.w(TAG, msg);
9436            throw new SecurityException(msg);
9437        }
9438        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9439        // with cross-user grant.
9440        return getContentProviderImpl(caller, name, null, stable, userId);
9441    }
9442
9443    public ContentProviderHolder getContentProviderExternal(
9444            String name, int userId, IBinder token) {
9445        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9446            "Do not have permission in call getContentProviderExternal()");
9447        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9448                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9449        return getContentProviderExternalUnchecked(name, token, userId);
9450    }
9451
9452    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9453            IBinder token, int userId) {
9454        return getContentProviderImpl(null, name, token, true, userId);
9455    }
9456
9457    /**
9458     * Drop a content provider from a ProcessRecord's bookkeeping
9459     */
9460    public void removeContentProvider(IBinder connection, boolean stable) {
9461        enforceNotIsolatedCaller("removeContentProvider");
9462        long ident = Binder.clearCallingIdentity();
9463        try {
9464            synchronized (this) {
9465                ContentProviderConnection conn;
9466                try {
9467                    conn = (ContentProviderConnection)connection;
9468                } catch (ClassCastException e) {
9469                    String msg ="removeContentProvider: " + connection
9470                            + " not a ContentProviderConnection";
9471                    Slog.w(TAG, msg);
9472                    throw new IllegalArgumentException(msg);
9473                }
9474                if (conn == null) {
9475                    throw new NullPointerException("connection is null");
9476                }
9477                if (decProviderCountLocked(conn, null, null, stable)) {
9478                    updateOomAdjLocked();
9479                }
9480            }
9481        } finally {
9482            Binder.restoreCallingIdentity(ident);
9483        }
9484    }
9485
9486    public void removeContentProviderExternal(String name, IBinder token) {
9487        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9488            "Do not have permission in call removeContentProviderExternal()");
9489        int userId = UserHandle.getCallingUserId();
9490        long ident = Binder.clearCallingIdentity();
9491        try {
9492            removeContentProviderExternalUnchecked(name, token, userId);
9493        } finally {
9494            Binder.restoreCallingIdentity(ident);
9495        }
9496    }
9497
9498    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9499        synchronized (this) {
9500            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9501            if(cpr == null) {
9502                //remove from mProvidersByClass
9503                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9504                return;
9505            }
9506
9507            //update content provider record entry info
9508            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9509            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9510            if (localCpr.hasExternalProcessHandles()) {
9511                if (localCpr.removeExternalProcessHandleLocked(token)) {
9512                    updateOomAdjLocked();
9513                } else {
9514                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9515                            + " with no external reference for token: "
9516                            + token + ".");
9517                }
9518            } else {
9519                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9520                        + " with no external references.");
9521            }
9522        }
9523    }
9524
9525    public final void publishContentProviders(IApplicationThread caller,
9526            List<ContentProviderHolder> providers) {
9527        if (providers == null) {
9528            return;
9529        }
9530
9531        enforceNotIsolatedCaller("publishContentProviders");
9532        synchronized (this) {
9533            final ProcessRecord r = getRecordForAppLocked(caller);
9534            if (DEBUG_MU)
9535                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9536            if (r == null) {
9537                throw new SecurityException(
9538                        "Unable to find app for caller " + caller
9539                      + " (pid=" + Binder.getCallingPid()
9540                      + ") when publishing content providers");
9541            }
9542
9543            final long origId = Binder.clearCallingIdentity();
9544
9545            final int N = providers.size();
9546            for (int i=0; i<N; i++) {
9547                ContentProviderHolder src = providers.get(i);
9548                if (src == null || src.info == null || src.provider == null) {
9549                    continue;
9550                }
9551                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9552                if (DEBUG_MU)
9553                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9554                if (dst != null) {
9555                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9556                    mProviderMap.putProviderByClass(comp, dst);
9557                    String names[] = dst.info.authority.split(";");
9558                    for (int j = 0; j < names.length; j++) {
9559                        mProviderMap.putProviderByName(names[j], dst);
9560                    }
9561
9562                    int NL = mLaunchingProviders.size();
9563                    int j;
9564                    for (j=0; j<NL; j++) {
9565                        if (mLaunchingProviders.get(j) == dst) {
9566                            mLaunchingProviders.remove(j);
9567                            j--;
9568                            NL--;
9569                        }
9570                    }
9571                    synchronized (dst) {
9572                        dst.provider = src.provider;
9573                        dst.proc = r;
9574                        dst.notifyAll();
9575                    }
9576                    updateOomAdjLocked(r);
9577                }
9578            }
9579
9580            Binder.restoreCallingIdentity(origId);
9581        }
9582    }
9583
9584    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9585        ContentProviderConnection conn;
9586        try {
9587            conn = (ContentProviderConnection)connection;
9588        } catch (ClassCastException e) {
9589            String msg ="refContentProvider: " + connection
9590                    + " not a ContentProviderConnection";
9591            Slog.w(TAG, msg);
9592            throw new IllegalArgumentException(msg);
9593        }
9594        if (conn == null) {
9595            throw new NullPointerException("connection is null");
9596        }
9597
9598        synchronized (this) {
9599            if (stable > 0) {
9600                conn.numStableIncs += stable;
9601            }
9602            stable = conn.stableCount + stable;
9603            if (stable < 0) {
9604                throw new IllegalStateException("stableCount < 0: " + stable);
9605            }
9606
9607            if (unstable > 0) {
9608                conn.numUnstableIncs += unstable;
9609            }
9610            unstable = conn.unstableCount + unstable;
9611            if (unstable < 0) {
9612                throw new IllegalStateException("unstableCount < 0: " + unstable);
9613            }
9614
9615            if ((stable+unstable) <= 0) {
9616                throw new IllegalStateException("ref counts can't go to zero here: stable="
9617                        + stable + " unstable=" + unstable);
9618            }
9619            conn.stableCount = stable;
9620            conn.unstableCount = unstable;
9621            return !conn.dead;
9622        }
9623    }
9624
9625    public void unstableProviderDied(IBinder connection) {
9626        ContentProviderConnection conn;
9627        try {
9628            conn = (ContentProviderConnection)connection;
9629        } catch (ClassCastException e) {
9630            String msg ="refContentProvider: " + connection
9631                    + " not a ContentProviderConnection";
9632            Slog.w(TAG, msg);
9633            throw new IllegalArgumentException(msg);
9634        }
9635        if (conn == null) {
9636            throw new NullPointerException("connection is null");
9637        }
9638
9639        // Safely retrieve the content provider associated with the connection.
9640        IContentProvider provider;
9641        synchronized (this) {
9642            provider = conn.provider.provider;
9643        }
9644
9645        if (provider == null) {
9646            // Um, yeah, we're way ahead of you.
9647            return;
9648        }
9649
9650        // Make sure the caller is being honest with us.
9651        if (provider.asBinder().pingBinder()) {
9652            // Er, no, still looks good to us.
9653            synchronized (this) {
9654                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9655                        + " says " + conn + " died, but we don't agree");
9656                return;
9657            }
9658        }
9659
9660        // Well look at that!  It's dead!
9661        synchronized (this) {
9662            if (conn.provider.provider != provider) {
9663                // But something changed...  good enough.
9664                return;
9665            }
9666
9667            ProcessRecord proc = conn.provider.proc;
9668            if (proc == null || proc.thread == null) {
9669                // Seems like the process is already cleaned up.
9670                return;
9671            }
9672
9673            // As far as we're concerned, this is just like receiving a
9674            // death notification...  just a bit prematurely.
9675            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9676                    + ") early provider death");
9677            final long ident = Binder.clearCallingIdentity();
9678            try {
9679                appDiedLocked(proc);
9680            } finally {
9681                Binder.restoreCallingIdentity(ident);
9682            }
9683        }
9684    }
9685
9686    @Override
9687    public void appNotRespondingViaProvider(IBinder connection) {
9688        enforceCallingPermission(
9689                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9690
9691        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9692        if (conn == null) {
9693            Slog.w(TAG, "ContentProviderConnection is null");
9694            return;
9695        }
9696
9697        final ProcessRecord host = conn.provider.proc;
9698        if (host == null) {
9699            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9700            return;
9701        }
9702
9703        final long token = Binder.clearCallingIdentity();
9704        try {
9705            appNotResponding(host, null, null, false, "ContentProvider not responding");
9706        } finally {
9707            Binder.restoreCallingIdentity(token);
9708        }
9709    }
9710
9711    public final void installSystemProviders() {
9712        List<ProviderInfo> providers;
9713        synchronized (this) {
9714            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9715            providers = generateApplicationProvidersLocked(app);
9716            if (providers != null) {
9717                for (int i=providers.size()-1; i>=0; i--) {
9718                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9719                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9720                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9721                                + ": not system .apk");
9722                        providers.remove(i);
9723                    }
9724                }
9725            }
9726        }
9727        if (providers != null) {
9728            mSystemThread.installSystemProviders(providers);
9729        }
9730
9731        mCoreSettingsObserver = new CoreSettingsObserver(this);
9732
9733        //mUsageStatsService.monitorPackages();
9734    }
9735
9736    /**
9737     * Allows apps to retrieve the MIME type of a URI.
9738     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9739     * users, then it does not need permission to access the ContentProvider.
9740     * Either, it needs cross-user uri grants.
9741     *
9742     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9743     *
9744     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9745     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9746     */
9747    public String getProviderMimeType(Uri uri, int userId) {
9748        enforceNotIsolatedCaller("getProviderMimeType");
9749        final String name = uri.getAuthority();
9750        int callingUid = Binder.getCallingUid();
9751        int callingPid = Binder.getCallingPid();
9752        long ident = 0;
9753        boolean clearedIdentity = false;
9754        userId = unsafeConvertIncomingUser(userId);
9755        if (canClearIdentity(callingPid, callingUid, userId)) {
9756            clearedIdentity = true;
9757            ident = Binder.clearCallingIdentity();
9758        }
9759        ContentProviderHolder holder = null;
9760        try {
9761            holder = getContentProviderExternalUnchecked(name, null, userId);
9762            if (holder != null) {
9763                return holder.provider.getType(uri);
9764            }
9765        } catch (RemoteException e) {
9766            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9767            return null;
9768        } finally {
9769            // We need to clear the identity to call removeContentProviderExternalUnchecked
9770            if (!clearedIdentity) {
9771                ident = Binder.clearCallingIdentity();
9772            }
9773            try {
9774                if (holder != null) {
9775                    removeContentProviderExternalUnchecked(name, null, userId);
9776                }
9777            } finally {
9778                Binder.restoreCallingIdentity(ident);
9779            }
9780        }
9781
9782        return null;
9783    }
9784
9785    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9786        if (UserHandle.getUserId(callingUid) == userId) {
9787            return true;
9788        }
9789        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9790                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9791                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9792                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9793                return true;
9794        }
9795        return false;
9796    }
9797
9798    // =========================================================
9799    // GLOBAL MANAGEMENT
9800    // =========================================================
9801
9802    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9803            boolean isolated, int isolatedUid) {
9804        String proc = customProcess != null ? customProcess : info.processName;
9805        BatteryStatsImpl.Uid.Proc ps = null;
9806        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9807        int uid = info.uid;
9808        if (isolated) {
9809            if (isolatedUid == 0) {
9810                int userId = UserHandle.getUserId(uid);
9811                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9812                while (true) {
9813                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9814                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9815                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9816                    }
9817                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9818                    mNextIsolatedProcessUid++;
9819                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9820                        // No process for this uid, use it.
9821                        break;
9822                    }
9823                    stepsLeft--;
9824                    if (stepsLeft <= 0) {
9825                        return null;
9826                    }
9827                }
9828            } else {
9829                // Special case for startIsolatedProcess (internal only), where
9830                // the uid of the isolated process is specified by the caller.
9831                uid = isolatedUid;
9832            }
9833        }
9834        return new ProcessRecord(stats, info, proc, uid);
9835    }
9836
9837    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9838            String abiOverride) {
9839        ProcessRecord app;
9840        if (!isolated) {
9841            app = getProcessRecordLocked(info.processName, info.uid, true);
9842        } else {
9843            app = null;
9844        }
9845
9846        if (app == null) {
9847            app = newProcessRecordLocked(info, null, isolated, 0);
9848            mProcessNames.put(info.processName, app.uid, app);
9849            if (isolated) {
9850                mIsolatedProcesses.put(app.uid, app);
9851            }
9852            updateLruProcessLocked(app, false, null);
9853            updateOomAdjLocked();
9854        }
9855
9856        // This package really, really can not be stopped.
9857        try {
9858            AppGlobals.getPackageManager().setPackageStoppedState(
9859                    info.packageName, false, UserHandle.getUserId(app.uid));
9860        } catch (RemoteException e) {
9861        } catch (IllegalArgumentException e) {
9862            Slog.w(TAG, "Failed trying to unstop package "
9863                    + info.packageName + ": " + e);
9864        }
9865
9866        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9867                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9868            app.persistent = true;
9869            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9870        }
9871        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9872            mPersistentStartingProcesses.add(app);
9873            startProcessLocked(app, "added application", app.processName, abiOverride,
9874                    null /* entryPoint */, null /* entryPointArgs */);
9875        }
9876
9877        return app;
9878    }
9879
9880    public void unhandledBack() {
9881        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9882                "unhandledBack()");
9883
9884        synchronized(this) {
9885            final long origId = Binder.clearCallingIdentity();
9886            try {
9887                getFocusedStack().unhandledBackLocked();
9888            } finally {
9889                Binder.restoreCallingIdentity(origId);
9890            }
9891        }
9892    }
9893
9894    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9895        enforceNotIsolatedCaller("openContentUri");
9896        final int userId = UserHandle.getCallingUserId();
9897        String name = uri.getAuthority();
9898        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9899        ParcelFileDescriptor pfd = null;
9900        if (cph != null) {
9901            // We record the binder invoker's uid in thread-local storage before
9902            // going to the content provider to open the file.  Later, in the code
9903            // that handles all permissions checks, we look for this uid and use
9904            // that rather than the Activity Manager's own uid.  The effect is that
9905            // we do the check against the caller's permissions even though it looks
9906            // to the content provider like the Activity Manager itself is making
9907            // the request.
9908            sCallerIdentity.set(new Identity(
9909                    Binder.getCallingPid(), Binder.getCallingUid()));
9910            try {
9911                pfd = cph.provider.openFile(null, uri, "r", null);
9912            } catch (FileNotFoundException e) {
9913                // do nothing; pfd will be returned null
9914            } finally {
9915                // Ensure that whatever happens, we clean up the identity state
9916                sCallerIdentity.remove();
9917            }
9918
9919            // We've got the fd now, so we're done with the provider.
9920            removeContentProviderExternalUnchecked(name, null, userId);
9921        } else {
9922            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9923        }
9924        return pfd;
9925    }
9926
9927    // Actually is sleeping or shutting down or whatever else in the future
9928    // is an inactive state.
9929    public boolean isSleepingOrShuttingDown() {
9930        return isSleeping() || mShuttingDown;
9931    }
9932
9933    public boolean isSleeping() {
9934        return mSleeping;
9935    }
9936
9937    void goingToSleep() {
9938        synchronized(this) {
9939            mWentToSleep = true;
9940            goToSleepIfNeededLocked();
9941        }
9942    }
9943
9944    void finishRunningVoiceLocked() {
9945        if (mRunningVoice) {
9946            mRunningVoice = false;
9947            goToSleepIfNeededLocked();
9948        }
9949    }
9950
9951    void goToSleepIfNeededLocked() {
9952        if (mWentToSleep && !mRunningVoice) {
9953            if (!mSleeping) {
9954                mSleeping = true;
9955                mStackSupervisor.goingToSleepLocked();
9956
9957                // Initialize the wake times of all processes.
9958                checkExcessivePowerUsageLocked(false);
9959                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9960                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9961                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9962            }
9963        }
9964    }
9965
9966    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9967        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9968            // Never persist the home stack.
9969            return;
9970        }
9971        mTaskPersister.wakeup(task, flush);
9972    }
9973
9974    @Override
9975    public boolean shutdown(int timeout) {
9976        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9977                != PackageManager.PERMISSION_GRANTED) {
9978            throw new SecurityException("Requires permission "
9979                    + android.Manifest.permission.SHUTDOWN);
9980        }
9981
9982        boolean timedout = false;
9983
9984        synchronized(this) {
9985            mShuttingDown = true;
9986            updateEventDispatchingLocked();
9987            timedout = mStackSupervisor.shutdownLocked(timeout);
9988        }
9989
9990        mAppOpsService.shutdown();
9991        if (mUsageStatsService != null) {
9992            mUsageStatsService.prepareShutdown();
9993        }
9994        mBatteryStatsService.shutdown();
9995        synchronized (this) {
9996            mProcessStats.shutdownLocked();
9997        }
9998        notifyTaskPersisterLocked(null, true);
9999
10000        return timedout;
10001    }
10002
10003    public final void activitySlept(IBinder token) {
10004        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10005
10006        final long origId = Binder.clearCallingIdentity();
10007
10008        synchronized (this) {
10009            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10010            if (r != null) {
10011                mStackSupervisor.activitySleptLocked(r);
10012            }
10013        }
10014
10015        Binder.restoreCallingIdentity(origId);
10016    }
10017
10018    private String lockScreenShownToString() {
10019        switch (mLockScreenShown) {
10020            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10021            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10022            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10023            default: return "Unknown=" + mLockScreenShown;
10024        }
10025    }
10026
10027    void logLockScreen(String msg) {
10028        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10029                " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" +
10030                mWentToSleep + " mSleeping=" + mSleeping);
10031    }
10032
10033    void comeOutOfSleepIfNeededLocked() {
10034        if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) {
10035            if (mSleeping) {
10036                mSleeping = false;
10037                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10038            }
10039        }
10040    }
10041
10042    void wakingUp() {
10043        synchronized(this) {
10044            mWentToSleep = false;
10045            comeOutOfSleepIfNeededLocked();
10046        }
10047    }
10048
10049    void startRunningVoiceLocked() {
10050        if (!mRunningVoice) {
10051            mRunningVoice = true;
10052            comeOutOfSleepIfNeededLocked();
10053        }
10054    }
10055
10056    private void updateEventDispatchingLocked() {
10057        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10058    }
10059
10060    public void setLockScreenShown(boolean shown) {
10061        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10062                != PackageManager.PERMISSION_GRANTED) {
10063            throw new SecurityException("Requires permission "
10064                    + android.Manifest.permission.DEVICE_POWER);
10065        }
10066
10067        synchronized(this) {
10068            long ident = Binder.clearCallingIdentity();
10069            try {
10070                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10071                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10072                comeOutOfSleepIfNeededLocked();
10073            } finally {
10074                Binder.restoreCallingIdentity(ident);
10075            }
10076        }
10077    }
10078
10079    @Override
10080    public void stopAppSwitches() {
10081        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10082                != PackageManager.PERMISSION_GRANTED) {
10083            throw new SecurityException("Requires permission "
10084                    + android.Manifest.permission.STOP_APP_SWITCHES);
10085        }
10086
10087        synchronized(this) {
10088            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10089                    + APP_SWITCH_DELAY_TIME;
10090            mDidAppSwitch = false;
10091            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10092            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10093            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10094        }
10095    }
10096
10097    public void resumeAppSwitches() {
10098        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10099                != PackageManager.PERMISSION_GRANTED) {
10100            throw new SecurityException("Requires permission "
10101                    + android.Manifest.permission.STOP_APP_SWITCHES);
10102        }
10103
10104        synchronized(this) {
10105            // Note that we don't execute any pending app switches... we will
10106            // let those wait until either the timeout, or the next start
10107            // activity request.
10108            mAppSwitchesAllowedTime = 0;
10109        }
10110    }
10111
10112    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10113            int callingPid, int callingUid, String name) {
10114        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10115            return true;
10116        }
10117
10118        int perm = checkComponentPermission(
10119                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10120                sourceUid, -1, true);
10121        if (perm == PackageManager.PERMISSION_GRANTED) {
10122            return true;
10123        }
10124
10125        // If the actual IPC caller is different from the logical source, then
10126        // also see if they are allowed to control app switches.
10127        if (callingUid != -1 && callingUid != sourceUid) {
10128            perm = checkComponentPermission(
10129                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10130                    callingUid, -1, true);
10131            if (perm == PackageManager.PERMISSION_GRANTED) {
10132                return true;
10133            }
10134        }
10135
10136        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10137        return false;
10138    }
10139
10140    public void setDebugApp(String packageName, boolean waitForDebugger,
10141            boolean persistent) {
10142        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10143                "setDebugApp()");
10144
10145        long ident = Binder.clearCallingIdentity();
10146        try {
10147            // Note that this is not really thread safe if there are multiple
10148            // callers into it at the same time, but that's not a situation we
10149            // care about.
10150            if (persistent) {
10151                final ContentResolver resolver = mContext.getContentResolver();
10152                Settings.Global.putString(
10153                    resolver, Settings.Global.DEBUG_APP,
10154                    packageName);
10155                Settings.Global.putInt(
10156                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10157                    waitForDebugger ? 1 : 0);
10158            }
10159
10160            synchronized (this) {
10161                if (!persistent) {
10162                    mOrigDebugApp = mDebugApp;
10163                    mOrigWaitForDebugger = mWaitForDebugger;
10164                }
10165                mDebugApp = packageName;
10166                mWaitForDebugger = waitForDebugger;
10167                mDebugTransient = !persistent;
10168                if (packageName != null) {
10169                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10170                            false, UserHandle.USER_ALL, "set debug app");
10171                }
10172            }
10173        } finally {
10174            Binder.restoreCallingIdentity(ident);
10175        }
10176    }
10177
10178    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
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
10187            mOpenGlTraceApp = processName;
10188        }
10189    }
10190
10191    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10192        synchronized (this) {
10193            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10194            if (!isDebuggable) {
10195                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10196                    throw new SecurityException("Process not debuggable: " + app.packageName);
10197                }
10198            }
10199            mProfileApp = processName;
10200            mProfileFile = profilerInfo.profileFile;
10201            if (mProfileFd != null) {
10202                try {
10203                    mProfileFd.close();
10204                } catch (IOException e) {
10205                }
10206                mProfileFd = null;
10207            }
10208            mProfileFd = profilerInfo.profileFd;
10209            mSamplingInterval = profilerInfo.samplingInterval;
10210            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10211            mProfileType = 0;
10212        }
10213    }
10214
10215    @Override
10216    public void setAlwaysFinish(boolean enabled) {
10217        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10218                "setAlwaysFinish()");
10219
10220        Settings.Global.putInt(
10221                mContext.getContentResolver(),
10222                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10223
10224        synchronized (this) {
10225            mAlwaysFinishActivities = enabled;
10226        }
10227    }
10228
10229    @Override
10230    public void setActivityController(IActivityController controller) {
10231        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10232                "setActivityController()");
10233        synchronized (this) {
10234            mController = controller;
10235            Watchdog.getInstance().setActivityController(controller);
10236        }
10237    }
10238
10239    @Override
10240    public void setUserIsMonkey(boolean userIsMonkey) {
10241        synchronized (this) {
10242            synchronized (mPidsSelfLocked) {
10243                final int callingPid = Binder.getCallingPid();
10244                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10245                if (precessRecord == null) {
10246                    throw new SecurityException("Unknown process: " + callingPid);
10247                }
10248                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10249                    throw new SecurityException("Only an instrumentation process "
10250                            + "with a UiAutomation can call setUserIsMonkey");
10251                }
10252            }
10253            mUserIsMonkey = userIsMonkey;
10254        }
10255    }
10256
10257    @Override
10258    public boolean isUserAMonkey() {
10259        synchronized (this) {
10260            // If there is a controller also implies the user is a monkey.
10261            return (mUserIsMonkey || mController != null);
10262        }
10263    }
10264
10265    public void requestBugReport() {
10266        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10267        SystemProperties.set("ctl.start", "bugreport");
10268    }
10269
10270    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10271        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10272    }
10273
10274    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10275        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10276            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10277        }
10278        return KEY_DISPATCHING_TIMEOUT;
10279    }
10280
10281    @Override
10282    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10283        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10284                != PackageManager.PERMISSION_GRANTED) {
10285            throw new SecurityException("Requires permission "
10286                    + android.Manifest.permission.FILTER_EVENTS);
10287        }
10288        ProcessRecord proc;
10289        long timeout;
10290        synchronized (this) {
10291            synchronized (mPidsSelfLocked) {
10292                proc = mPidsSelfLocked.get(pid);
10293            }
10294            timeout = getInputDispatchingTimeoutLocked(proc);
10295        }
10296
10297        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10298            return -1;
10299        }
10300
10301        return timeout;
10302    }
10303
10304    /**
10305     * Handle input dispatching timeouts.
10306     * Returns whether input dispatching should be aborted or not.
10307     */
10308    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10309            final ActivityRecord activity, final ActivityRecord parent,
10310            final boolean aboveSystem, String reason) {
10311        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10312                != PackageManager.PERMISSION_GRANTED) {
10313            throw new SecurityException("Requires permission "
10314                    + android.Manifest.permission.FILTER_EVENTS);
10315        }
10316
10317        final String annotation;
10318        if (reason == null) {
10319            annotation = "Input dispatching timed out";
10320        } else {
10321            annotation = "Input dispatching timed out (" + reason + ")";
10322        }
10323
10324        if (proc != null) {
10325            synchronized (this) {
10326                if (proc.debugging) {
10327                    return false;
10328                }
10329
10330                if (mDidDexOpt) {
10331                    // Give more time since we were dexopting.
10332                    mDidDexOpt = false;
10333                    return false;
10334                }
10335
10336                if (proc.instrumentationClass != null) {
10337                    Bundle info = new Bundle();
10338                    info.putString("shortMsg", "keyDispatchingTimedOut");
10339                    info.putString("longMsg", annotation);
10340                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10341                    return true;
10342                }
10343            }
10344            mHandler.post(new Runnable() {
10345                @Override
10346                public void run() {
10347                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10348                }
10349            });
10350        }
10351
10352        return true;
10353    }
10354
10355    public Bundle getAssistContextExtras(int requestType) {
10356        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10357                UserHandle.getCallingUserId());
10358        if (pae == null) {
10359            return null;
10360        }
10361        synchronized (pae) {
10362            while (!pae.haveResult) {
10363                try {
10364                    pae.wait();
10365                } catch (InterruptedException e) {
10366                }
10367            }
10368            if (pae.result != null) {
10369                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10370            }
10371        }
10372        synchronized (this) {
10373            mPendingAssistExtras.remove(pae);
10374            mHandler.removeCallbacks(pae);
10375        }
10376        return pae.extras;
10377    }
10378
10379    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10380            int userHandle) {
10381        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10382                "getAssistContextExtras()");
10383        PendingAssistExtras pae;
10384        Bundle extras = new Bundle();
10385        synchronized (this) {
10386            ActivityRecord activity = getFocusedStack().mResumedActivity;
10387            if (activity == null) {
10388                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10389                return null;
10390            }
10391            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10392            if (activity.app == null || activity.app.thread == null) {
10393                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10394                return null;
10395            }
10396            if (activity.app.pid == Binder.getCallingPid()) {
10397                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10398                return null;
10399            }
10400            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10401            try {
10402                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10403                        requestType);
10404                mPendingAssistExtras.add(pae);
10405                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10406            } catch (RemoteException e) {
10407                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10408                return null;
10409            }
10410            return pae;
10411        }
10412    }
10413
10414    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10415        PendingAssistExtras pae = (PendingAssistExtras)token;
10416        synchronized (pae) {
10417            pae.result = extras;
10418            pae.haveResult = true;
10419            pae.notifyAll();
10420            if (pae.intent == null) {
10421                // Caller is just waiting for the result.
10422                return;
10423            }
10424        }
10425
10426        // We are now ready to launch the assist activity.
10427        synchronized (this) {
10428            boolean exists = mPendingAssistExtras.remove(pae);
10429            mHandler.removeCallbacks(pae);
10430            if (!exists) {
10431                // Timed out.
10432                return;
10433            }
10434        }
10435        pae.intent.replaceExtras(extras);
10436        if (pae.hint != null) {
10437            pae.intent.putExtra(pae.hint, true);
10438        }
10439        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10440                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10441                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10442        closeSystemDialogs("assist");
10443        try {
10444            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10445        } catch (ActivityNotFoundException e) {
10446            Slog.w(TAG, "No activity to handle assist action.", e);
10447        }
10448    }
10449
10450    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10451        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10452    }
10453
10454    public void registerProcessObserver(IProcessObserver observer) {
10455        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10456                "registerProcessObserver()");
10457        synchronized (this) {
10458            mProcessObservers.register(observer);
10459        }
10460    }
10461
10462    @Override
10463    public void unregisterProcessObserver(IProcessObserver observer) {
10464        synchronized (this) {
10465            mProcessObservers.unregister(observer);
10466        }
10467    }
10468
10469    @Override
10470    public boolean convertFromTranslucent(IBinder token) {
10471        final long origId = Binder.clearCallingIdentity();
10472        try {
10473            synchronized (this) {
10474                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10475                if (r == null) {
10476                    return false;
10477                }
10478                final boolean translucentChanged = r.changeWindowTranslucency(true);
10479                if (translucentChanged) {
10480                    r.task.stack.releaseBackgroundResources();
10481                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10482                }
10483                mWindowManager.setAppFullscreen(token, true);
10484                return translucentChanged;
10485            }
10486        } finally {
10487            Binder.restoreCallingIdentity(origId);
10488        }
10489    }
10490
10491    @Override
10492    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10493        final long origId = Binder.clearCallingIdentity();
10494        try {
10495            synchronized (this) {
10496                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10497                if (r == null) {
10498                    return false;
10499                }
10500                int index = r.task.mActivities.lastIndexOf(r);
10501                if (index > 0) {
10502                    ActivityRecord under = r.task.mActivities.get(index - 1);
10503                    under.returningOptions = options;
10504                }
10505                final boolean translucentChanged = r.changeWindowTranslucency(false);
10506                if (translucentChanged) {
10507                    r.task.stack.convertToTranslucent(r);
10508                }
10509                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10510                mWindowManager.setAppFullscreen(token, false);
10511                return translucentChanged;
10512            }
10513        } finally {
10514            Binder.restoreCallingIdentity(origId);
10515        }
10516    }
10517
10518    @Override
10519    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10520        final long origId = Binder.clearCallingIdentity();
10521        try {
10522            synchronized (this) {
10523                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10524                if (r != null) {
10525                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10526                }
10527            }
10528            return false;
10529        } finally {
10530            Binder.restoreCallingIdentity(origId);
10531        }
10532    }
10533
10534    @Override
10535    public boolean isBackgroundVisibleBehind(IBinder token) {
10536        final long origId = Binder.clearCallingIdentity();
10537        try {
10538            synchronized (this) {
10539                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10540                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10541                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10542                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10543                return visible;
10544            }
10545        } finally {
10546            Binder.restoreCallingIdentity(origId);
10547        }
10548    }
10549
10550    @Override
10551    public ActivityOptions getActivityOptions(IBinder token) {
10552        final long origId = Binder.clearCallingIdentity();
10553        try {
10554            synchronized (this) {
10555                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10556                if (r != null) {
10557                    final ActivityOptions activityOptions = r.pendingOptions;
10558                    r.pendingOptions = null;
10559                    return activityOptions;
10560                }
10561                return null;
10562            }
10563        } finally {
10564            Binder.restoreCallingIdentity(origId);
10565        }
10566    }
10567
10568    @Override
10569    public void setImmersive(IBinder token, boolean immersive) {
10570        synchronized(this) {
10571            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10572            if (r == null) {
10573                throw new IllegalArgumentException();
10574            }
10575            r.immersive = immersive;
10576
10577            // update associated state if we're frontmost
10578            if (r == mFocusedActivity) {
10579                if (DEBUG_IMMERSIVE) {
10580                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10581                }
10582                applyUpdateLockStateLocked(r);
10583            }
10584        }
10585    }
10586
10587    @Override
10588    public boolean isImmersive(IBinder token) {
10589        synchronized (this) {
10590            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10591            if (r == null) {
10592                throw new IllegalArgumentException();
10593            }
10594            return r.immersive;
10595        }
10596    }
10597
10598    public boolean isTopActivityImmersive() {
10599        enforceNotIsolatedCaller("startActivity");
10600        synchronized (this) {
10601            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10602            return (r != null) ? r.immersive : false;
10603        }
10604    }
10605
10606    @Override
10607    public boolean isTopOfTask(IBinder token) {
10608        synchronized (this) {
10609            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10610            if (r == null) {
10611                throw new IllegalArgumentException();
10612            }
10613            return r.task.getTopActivity() == r;
10614        }
10615    }
10616
10617    public final void enterSafeMode() {
10618        synchronized(this) {
10619            // It only makes sense to do this before the system is ready
10620            // and started launching other packages.
10621            if (!mSystemReady) {
10622                try {
10623                    AppGlobals.getPackageManager().enterSafeMode();
10624                } catch (RemoteException e) {
10625                }
10626            }
10627
10628            mSafeMode = true;
10629        }
10630    }
10631
10632    public final void showSafeModeOverlay() {
10633        View v = LayoutInflater.from(mContext).inflate(
10634                com.android.internal.R.layout.safe_mode, null);
10635        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10636        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10637        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10638        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10639        lp.gravity = Gravity.BOTTOM | Gravity.START;
10640        lp.format = v.getBackground().getOpacity();
10641        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10642                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10643        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10644        ((WindowManager)mContext.getSystemService(
10645                Context.WINDOW_SERVICE)).addView(v, lp);
10646    }
10647
10648    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10649        if (!(sender instanceof PendingIntentRecord)) {
10650            return;
10651        }
10652        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10653        synchronized (stats) {
10654            if (mBatteryStatsService.isOnBattery()) {
10655                mBatteryStatsService.enforceCallingPermission();
10656                PendingIntentRecord rec = (PendingIntentRecord)sender;
10657                int MY_UID = Binder.getCallingUid();
10658                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10659                BatteryStatsImpl.Uid.Pkg pkg =
10660                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10661                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10662                pkg.incWakeupsLocked();
10663            }
10664        }
10665    }
10666
10667    public boolean killPids(int[] pids, String pReason, boolean secure) {
10668        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10669            throw new SecurityException("killPids only available to the system");
10670        }
10671        String reason = (pReason == null) ? "Unknown" : pReason;
10672        // XXX Note: don't acquire main activity lock here, because the window
10673        // manager calls in with its locks held.
10674
10675        boolean killed = false;
10676        synchronized (mPidsSelfLocked) {
10677            int[] types = new int[pids.length];
10678            int worstType = 0;
10679            for (int i=0; i<pids.length; i++) {
10680                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10681                if (proc != null) {
10682                    int type = proc.setAdj;
10683                    types[i] = type;
10684                    if (type > worstType) {
10685                        worstType = type;
10686                    }
10687                }
10688            }
10689
10690            // If the worst oom_adj is somewhere in the cached proc LRU range,
10691            // then constrain it so we will kill all cached procs.
10692            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10693                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10694                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10695            }
10696
10697            // If this is not a secure call, don't let it kill processes that
10698            // are important.
10699            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10700                worstType = ProcessList.SERVICE_ADJ;
10701            }
10702
10703            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10704            for (int i=0; i<pids.length; i++) {
10705                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10706                if (proc == null) {
10707                    continue;
10708                }
10709                int adj = proc.setAdj;
10710                if (adj >= worstType && !proc.killedByAm) {
10711                    proc.kill(reason, true);
10712                    killed = true;
10713                }
10714            }
10715        }
10716        return killed;
10717    }
10718
10719    @Override
10720    public void killUid(int uid, String reason) {
10721        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10722            throw new SecurityException("killUid only available to the system");
10723        }
10724        synchronized (this) {
10725            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10726                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10727                    reason != null ? reason : "kill uid");
10728        }
10729    }
10730
10731    @Override
10732    public boolean killProcessesBelowForeground(String reason) {
10733        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10734            throw new SecurityException("killProcessesBelowForeground() only available to system");
10735        }
10736
10737        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10738    }
10739
10740    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10741        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10742            throw new SecurityException("killProcessesBelowAdj() only available to system");
10743        }
10744
10745        boolean killed = false;
10746        synchronized (mPidsSelfLocked) {
10747            final int size = mPidsSelfLocked.size();
10748            for (int i = 0; i < size; i++) {
10749                final int pid = mPidsSelfLocked.keyAt(i);
10750                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10751                if (proc == null) continue;
10752
10753                final int adj = proc.setAdj;
10754                if (adj > belowAdj && !proc.killedByAm) {
10755                    proc.kill(reason, true);
10756                    killed = true;
10757                }
10758            }
10759        }
10760        return killed;
10761    }
10762
10763    @Override
10764    public void hang(final IBinder who, boolean allowRestart) {
10765        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10766                != PackageManager.PERMISSION_GRANTED) {
10767            throw new SecurityException("Requires permission "
10768                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10769        }
10770
10771        final IBinder.DeathRecipient death = new DeathRecipient() {
10772            @Override
10773            public void binderDied() {
10774                synchronized (this) {
10775                    notifyAll();
10776                }
10777            }
10778        };
10779
10780        try {
10781            who.linkToDeath(death, 0);
10782        } catch (RemoteException e) {
10783            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10784            return;
10785        }
10786
10787        synchronized (this) {
10788            Watchdog.getInstance().setAllowRestart(allowRestart);
10789            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10790            synchronized (death) {
10791                while (who.isBinderAlive()) {
10792                    try {
10793                        death.wait();
10794                    } catch (InterruptedException e) {
10795                    }
10796                }
10797            }
10798            Watchdog.getInstance().setAllowRestart(true);
10799        }
10800    }
10801
10802    @Override
10803    public void restart() {
10804        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10805                != PackageManager.PERMISSION_GRANTED) {
10806            throw new SecurityException("Requires permission "
10807                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10808        }
10809
10810        Log.i(TAG, "Sending shutdown broadcast...");
10811
10812        BroadcastReceiver br = new BroadcastReceiver() {
10813            @Override public void onReceive(Context context, Intent intent) {
10814                // Now the broadcast is done, finish up the low-level shutdown.
10815                Log.i(TAG, "Shutting down activity manager...");
10816                shutdown(10000);
10817                Log.i(TAG, "Shutdown complete, restarting!");
10818                Process.killProcess(Process.myPid());
10819                System.exit(10);
10820            }
10821        };
10822
10823        // First send the high-level shut down broadcast.
10824        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10825        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10826        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10827        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10828        mContext.sendOrderedBroadcastAsUser(intent,
10829                UserHandle.ALL, null, br, mHandler, 0, null, null);
10830        */
10831        br.onReceive(mContext, intent);
10832    }
10833
10834    private long getLowRamTimeSinceIdle(long now) {
10835        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10836    }
10837
10838    @Override
10839    public void performIdleMaintenance() {
10840        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10841                != PackageManager.PERMISSION_GRANTED) {
10842            throw new SecurityException("Requires permission "
10843                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10844        }
10845
10846        synchronized (this) {
10847            final long now = SystemClock.uptimeMillis();
10848            final long timeSinceLastIdle = now - mLastIdleTime;
10849            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10850            mLastIdleTime = now;
10851            mLowRamTimeSinceLastIdle = 0;
10852            if (mLowRamStartTime != 0) {
10853                mLowRamStartTime = now;
10854            }
10855
10856            StringBuilder sb = new StringBuilder(128);
10857            sb.append("Idle maintenance over ");
10858            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10859            sb.append(" low RAM for ");
10860            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10861            Slog.i(TAG, sb.toString());
10862
10863            // If at least 1/3 of our time since the last idle period has been spent
10864            // with RAM low, then we want to kill processes.
10865            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10866
10867            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10868                ProcessRecord proc = mLruProcesses.get(i);
10869                if (proc.notCachedSinceIdle) {
10870                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10871                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10872                        if (doKilling && proc.initialIdlePss != 0
10873                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10874                            proc.kill("idle maint (pss " + proc.lastPss
10875                                    + " from " + proc.initialIdlePss + ")", true);
10876                        }
10877                    }
10878                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10879                    proc.notCachedSinceIdle = true;
10880                    proc.initialIdlePss = 0;
10881                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10882                            isSleeping(), now);
10883                }
10884            }
10885
10886            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10887            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10888        }
10889    }
10890
10891    private void retrieveSettings() {
10892        final ContentResolver resolver = mContext.getContentResolver();
10893        String debugApp = Settings.Global.getString(
10894            resolver, Settings.Global.DEBUG_APP);
10895        boolean waitForDebugger = Settings.Global.getInt(
10896            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10897        boolean alwaysFinishActivities = Settings.Global.getInt(
10898            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10899        boolean forceRtl = Settings.Global.getInt(
10900                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10901        // Transfer any global setting for forcing RTL layout, into a System Property
10902        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10903
10904        Configuration configuration = new Configuration();
10905        Settings.System.getConfiguration(resolver, configuration);
10906        if (forceRtl) {
10907            // This will take care of setting the correct layout direction flags
10908            configuration.setLayoutDirection(configuration.locale);
10909        }
10910
10911        synchronized (this) {
10912            mDebugApp = mOrigDebugApp = debugApp;
10913            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10914            mAlwaysFinishActivities = alwaysFinishActivities;
10915            // This happens before any activities are started, so we can
10916            // change mConfiguration in-place.
10917            updateConfigurationLocked(configuration, null, false, true);
10918            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10919        }
10920    }
10921
10922    /** Loads resources after the current configuration has been set. */
10923    private void loadResourcesOnSystemReady() {
10924        final Resources res = mContext.getResources();
10925        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10926        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10927        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10928    }
10929
10930    public boolean testIsSystemReady() {
10931        // no need to synchronize(this) just to read & return the value
10932        return mSystemReady;
10933    }
10934
10935    private static File getCalledPreBootReceiversFile() {
10936        File dataDir = Environment.getDataDirectory();
10937        File systemDir = new File(dataDir, "system");
10938        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10939        return fname;
10940    }
10941
10942    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10943        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10944        File file = getCalledPreBootReceiversFile();
10945        FileInputStream fis = null;
10946        try {
10947            fis = new FileInputStream(file);
10948            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10949            int fvers = dis.readInt();
10950            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10951                String vers = dis.readUTF();
10952                String codename = dis.readUTF();
10953                String build = dis.readUTF();
10954                if (android.os.Build.VERSION.RELEASE.equals(vers)
10955                        && android.os.Build.VERSION.CODENAME.equals(codename)
10956                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10957                    int num = dis.readInt();
10958                    while (num > 0) {
10959                        num--;
10960                        String pkg = dis.readUTF();
10961                        String cls = dis.readUTF();
10962                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10963                    }
10964                }
10965            }
10966        } catch (FileNotFoundException e) {
10967        } catch (IOException e) {
10968            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10969        } finally {
10970            if (fis != null) {
10971                try {
10972                    fis.close();
10973                } catch (IOException e) {
10974                }
10975            }
10976        }
10977        return lastDoneReceivers;
10978    }
10979
10980    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10981        File file = getCalledPreBootReceiversFile();
10982        FileOutputStream fos = null;
10983        DataOutputStream dos = null;
10984        try {
10985            fos = new FileOutputStream(file);
10986            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10987            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10988            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10989            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10990            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10991            dos.writeInt(list.size());
10992            for (int i=0; i<list.size(); i++) {
10993                dos.writeUTF(list.get(i).getPackageName());
10994                dos.writeUTF(list.get(i).getClassName());
10995            }
10996        } catch (IOException e) {
10997            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10998            file.delete();
10999        } finally {
11000            FileUtils.sync(fos);
11001            if (dos != null) {
11002                try {
11003                    dos.close();
11004                } catch (IOException e) {
11005                    // TODO Auto-generated catch block
11006                    e.printStackTrace();
11007                }
11008            }
11009        }
11010    }
11011
11012    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11013            ArrayList<ComponentName> doneReceivers, int userId) {
11014        boolean waitingUpdate = false;
11015        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11016        List<ResolveInfo> ris = null;
11017        try {
11018            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11019                    intent, null, 0, userId);
11020        } catch (RemoteException e) {
11021        }
11022        if (ris != null) {
11023            for (int i=ris.size()-1; i>=0; i--) {
11024                if ((ris.get(i).activityInfo.applicationInfo.flags
11025                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11026                    ris.remove(i);
11027                }
11028            }
11029            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11030
11031            // For User 0, load the version number. When delivering to a new user, deliver
11032            // to all receivers.
11033            if (userId == UserHandle.USER_OWNER) {
11034                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11035                for (int i=0; i<ris.size(); i++) {
11036                    ActivityInfo ai = ris.get(i).activityInfo;
11037                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11038                    if (lastDoneReceivers.contains(comp)) {
11039                        // We already did the pre boot receiver for this app with the current
11040                        // platform version, so don't do it again...
11041                        ris.remove(i);
11042                        i--;
11043                        // ...however, do keep it as one that has been done, so we don't
11044                        // forget about it when rewriting the file of last done receivers.
11045                        doneReceivers.add(comp);
11046                    }
11047                }
11048            }
11049
11050            // If primary user, send broadcast to all available users, else just to userId
11051            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11052                    : new int[] { userId };
11053            for (int i = 0; i < ris.size(); i++) {
11054                ActivityInfo ai = ris.get(i).activityInfo;
11055                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11056                doneReceivers.add(comp);
11057                intent.setComponent(comp);
11058                for (int j=0; j<users.length; j++) {
11059                    IIntentReceiver finisher = null;
11060                    // On last receiver and user, set up a completion callback
11061                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11062                        finisher = new IIntentReceiver.Stub() {
11063                            public void performReceive(Intent intent, int resultCode,
11064                                    String data, Bundle extras, boolean ordered,
11065                                    boolean sticky, int sendingUser) {
11066                                // The raw IIntentReceiver interface is called
11067                                // with the AM lock held, so redispatch to
11068                                // execute our code without the lock.
11069                                mHandler.post(onFinishCallback);
11070                            }
11071                        };
11072                    }
11073                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11074                            + " for user " + users[j]);
11075                    broadcastIntentLocked(null, null, intent, null, finisher,
11076                            0, null, null, null, AppOpsManager.OP_NONE,
11077                            true, false, MY_PID, Process.SYSTEM_UID,
11078                            users[j]);
11079                    if (finisher != null) {
11080                        waitingUpdate = true;
11081                    }
11082                }
11083            }
11084        }
11085
11086        return waitingUpdate;
11087    }
11088
11089    public void systemReady(final Runnable goingCallback) {
11090        synchronized(this) {
11091            if (mSystemReady) {
11092                // If we're done calling all the receivers, run the next "boot phase" passed in
11093                // by the SystemServer
11094                if (goingCallback != null) {
11095                    goingCallback.run();
11096                }
11097                return;
11098            }
11099
11100            // Make sure we have the current profile info, since it is needed for
11101            // security checks.
11102            updateCurrentProfileIdsLocked();
11103
11104            if (mRecentTasks == null) {
11105                mRecentTasks = mTaskPersister.restoreTasksLocked();
11106                if (!mRecentTasks.isEmpty()) {
11107                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11108                }
11109                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11110                mTaskPersister.startPersisting();
11111            }
11112
11113            // Check to see if there are any update receivers to run.
11114            if (!mDidUpdate) {
11115                if (mWaitingUpdate) {
11116                    return;
11117                }
11118                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11119                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11120                    public void run() {
11121                        synchronized (ActivityManagerService.this) {
11122                            mDidUpdate = true;
11123                        }
11124                        writeLastDonePreBootReceivers(doneReceivers);
11125                        showBootMessage(mContext.getText(
11126                                R.string.android_upgrading_complete),
11127                                false);
11128                        systemReady(goingCallback);
11129                    }
11130                }, doneReceivers, UserHandle.USER_OWNER);
11131
11132                if (mWaitingUpdate) {
11133                    return;
11134                }
11135                mDidUpdate = true;
11136            }
11137
11138            mAppOpsService.systemReady();
11139            mSystemReady = true;
11140        }
11141
11142        ArrayList<ProcessRecord> procsToKill = null;
11143        synchronized(mPidsSelfLocked) {
11144            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11145                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11146                if (!isAllowedWhileBooting(proc.info)){
11147                    if (procsToKill == null) {
11148                        procsToKill = new ArrayList<ProcessRecord>();
11149                    }
11150                    procsToKill.add(proc);
11151                }
11152            }
11153        }
11154
11155        synchronized(this) {
11156            if (procsToKill != null) {
11157                for (int i=procsToKill.size()-1; i>=0; i--) {
11158                    ProcessRecord proc = procsToKill.get(i);
11159                    Slog.i(TAG, "Removing system update proc: " + proc);
11160                    removeProcessLocked(proc, true, false, "system update done");
11161                }
11162            }
11163
11164            // Now that we have cleaned up any update processes, we
11165            // are ready to start launching real processes and know that
11166            // we won't trample on them any more.
11167            mProcessesReady = true;
11168        }
11169
11170        Slog.i(TAG, "System now ready");
11171        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11172            SystemClock.uptimeMillis());
11173
11174        synchronized(this) {
11175            // Make sure we have no pre-ready processes sitting around.
11176
11177            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11178                ResolveInfo ri = mContext.getPackageManager()
11179                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11180                                STOCK_PM_FLAGS);
11181                CharSequence errorMsg = null;
11182                if (ri != null) {
11183                    ActivityInfo ai = ri.activityInfo;
11184                    ApplicationInfo app = ai.applicationInfo;
11185                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11186                        mTopAction = Intent.ACTION_FACTORY_TEST;
11187                        mTopData = null;
11188                        mTopComponent = new ComponentName(app.packageName,
11189                                ai.name);
11190                    } else {
11191                        errorMsg = mContext.getResources().getText(
11192                                com.android.internal.R.string.factorytest_not_system);
11193                    }
11194                } else {
11195                    errorMsg = mContext.getResources().getText(
11196                            com.android.internal.R.string.factorytest_no_action);
11197                }
11198                if (errorMsg != null) {
11199                    mTopAction = null;
11200                    mTopData = null;
11201                    mTopComponent = null;
11202                    Message msg = Message.obtain();
11203                    msg.what = SHOW_FACTORY_ERROR_MSG;
11204                    msg.getData().putCharSequence("msg", errorMsg);
11205                    mHandler.sendMessage(msg);
11206                }
11207            }
11208        }
11209
11210        retrieveSettings();
11211        loadResourcesOnSystemReady();
11212
11213        synchronized (this) {
11214            readGrantedUriPermissionsLocked();
11215        }
11216
11217        if (goingCallback != null) goingCallback.run();
11218
11219        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11220                Integer.toString(mCurrentUserId), mCurrentUserId);
11221        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11222                Integer.toString(mCurrentUserId), mCurrentUserId);
11223        mSystemServiceManager.startUser(mCurrentUserId);
11224
11225        synchronized (this) {
11226            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11227                try {
11228                    List apps = AppGlobals.getPackageManager().
11229                        getPersistentApplications(STOCK_PM_FLAGS);
11230                    if (apps != null) {
11231                        int N = apps.size();
11232                        int i;
11233                        for (i=0; i<N; i++) {
11234                            ApplicationInfo info
11235                                = (ApplicationInfo)apps.get(i);
11236                            if (info != null &&
11237                                    !info.packageName.equals("android")) {
11238                                addAppLocked(info, false, null /* ABI override */);
11239                            }
11240                        }
11241                    }
11242                } catch (RemoteException ex) {
11243                    // pm is in same process, this will never happen.
11244                }
11245            }
11246
11247            // Start up initial activity.
11248            mBooting = true;
11249            startHomeActivityLocked(mCurrentUserId);
11250
11251            try {
11252                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11253                    Message msg = Message.obtain();
11254                    msg.what = SHOW_UID_ERROR_MSG;
11255                    mHandler.sendMessage(msg);
11256                }
11257            } catch (RemoteException e) {
11258            }
11259
11260            long ident = Binder.clearCallingIdentity();
11261            try {
11262                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11263                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11264                        | Intent.FLAG_RECEIVER_FOREGROUND);
11265                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11266                broadcastIntentLocked(null, null, intent,
11267                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11268                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11269                intent = new Intent(Intent.ACTION_USER_STARTING);
11270                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11271                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11272                broadcastIntentLocked(null, null, intent,
11273                        null, new IIntentReceiver.Stub() {
11274                            @Override
11275                            public void performReceive(Intent intent, int resultCode, String data,
11276                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11277                                    throws RemoteException {
11278                            }
11279                        }, 0, null, null,
11280                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11281                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11282            } catch (Throwable t) {
11283                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11284            } finally {
11285                Binder.restoreCallingIdentity(ident);
11286            }
11287            mStackSupervisor.resumeTopActivitiesLocked();
11288            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11289        }
11290    }
11291
11292    private boolean makeAppCrashingLocked(ProcessRecord app,
11293            String shortMsg, String longMsg, String stackTrace) {
11294        app.crashing = true;
11295        app.crashingReport = generateProcessError(app,
11296                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11297        startAppProblemLocked(app);
11298        app.stopFreezingAllLocked();
11299        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11300    }
11301
11302    private void makeAppNotRespondingLocked(ProcessRecord app,
11303            String activity, String shortMsg, String longMsg) {
11304        app.notResponding = true;
11305        app.notRespondingReport = generateProcessError(app,
11306                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11307                activity, shortMsg, longMsg, null);
11308        startAppProblemLocked(app);
11309        app.stopFreezingAllLocked();
11310    }
11311
11312    /**
11313     * Generate a process error record, suitable for attachment to a ProcessRecord.
11314     *
11315     * @param app The ProcessRecord in which the error occurred.
11316     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11317     *                      ActivityManager.AppErrorStateInfo
11318     * @param activity The activity associated with the crash, if known.
11319     * @param shortMsg Short message describing the crash.
11320     * @param longMsg Long message describing the crash.
11321     * @param stackTrace Full crash stack trace, may be null.
11322     *
11323     * @return Returns a fully-formed AppErrorStateInfo record.
11324     */
11325    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11326            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11327        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11328
11329        report.condition = condition;
11330        report.processName = app.processName;
11331        report.pid = app.pid;
11332        report.uid = app.info.uid;
11333        report.tag = activity;
11334        report.shortMsg = shortMsg;
11335        report.longMsg = longMsg;
11336        report.stackTrace = stackTrace;
11337
11338        return report;
11339    }
11340
11341    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11342        synchronized (this) {
11343            app.crashing = false;
11344            app.crashingReport = null;
11345            app.notResponding = false;
11346            app.notRespondingReport = null;
11347            if (app.anrDialog == fromDialog) {
11348                app.anrDialog = null;
11349            }
11350            if (app.waitDialog == fromDialog) {
11351                app.waitDialog = null;
11352            }
11353            if (app.pid > 0 && app.pid != MY_PID) {
11354                handleAppCrashLocked(app, null, null, null);
11355                app.kill("user request after error", true);
11356            }
11357        }
11358    }
11359
11360    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11361            String stackTrace) {
11362        long now = SystemClock.uptimeMillis();
11363
11364        Long crashTime;
11365        if (!app.isolated) {
11366            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11367        } else {
11368            crashTime = null;
11369        }
11370        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11371            // This process loses!
11372            Slog.w(TAG, "Process " + app.info.processName
11373                    + " has crashed too many times: killing!");
11374            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11375                    app.userId, app.info.processName, app.uid);
11376            mStackSupervisor.handleAppCrashLocked(app);
11377            if (!app.persistent) {
11378                // We don't want to start this process again until the user
11379                // explicitly does so...  but for persistent process, we really
11380                // need to keep it running.  If a persistent process is actually
11381                // repeatedly crashing, then badness for everyone.
11382                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11383                        app.info.processName);
11384                if (!app.isolated) {
11385                    // XXX We don't have a way to mark isolated processes
11386                    // as bad, since they don't have a peristent identity.
11387                    mBadProcesses.put(app.info.processName, app.uid,
11388                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11389                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11390                }
11391                app.bad = true;
11392                app.removed = true;
11393                // Don't let services in this process be restarted and potentially
11394                // annoy the user repeatedly.  Unless it is persistent, since those
11395                // processes run critical code.
11396                removeProcessLocked(app, false, false, "crash");
11397                mStackSupervisor.resumeTopActivitiesLocked();
11398                return false;
11399            }
11400            mStackSupervisor.resumeTopActivitiesLocked();
11401        } else {
11402            mStackSupervisor.finishTopRunningActivityLocked(app);
11403        }
11404
11405        // Bump up the crash count of any services currently running in the proc.
11406        for (int i=app.services.size()-1; i>=0; i--) {
11407            // Any services running in the application need to be placed
11408            // back in the pending list.
11409            ServiceRecord sr = app.services.valueAt(i);
11410            sr.crashCount++;
11411        }
11412
11413        // If the crashing process is what we consider to be the "home process" and it has been
11414        // replaced by a third-party app, clear the package preferred activities from packages
11415        // with a home activity running in the process to prevent a repeatedly crashing app
11416        // from blocking the user to manually clear the list.
11417        final ArrayList<ActivityRecord> activities = app.activities;
11418        if (app == mHomeProcess && activities.size() > 0
11419                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11420            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11421                final ActivityRecord r = activities.get(activityNdx);
11422                if (r.isHomeActivity()) {
11423                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11424                    try {
11425                        ActivityThread.getPackageManager()
11426                                .clearPackagePreferredActivities(r.packageName);
11427                    } catch (RemoteException c) {
11428                        // pm is in same process, this will never happen.
11429                    }
11430                }
11431            }
11432        }
11433
11434        if (!app.isolated) {
11435            // XXX Can't keep track of crash times for isolated processes,
11436            // because they don't have a perisistent identity.
11437            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11438        }
11439
11440        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11441        return true;
11442    }
11443
11444    void startAppProblemLocked(ProcessRecord app) {
11445        // If this app is not running under the current user, then we
11446        // can't give it a report button because that would require
11447        // launching the report UI under a different user.
11448        app.errorReportReceiver = null;
11449
11450        for (int userId : mCurrentProfileIds) {
11451            if (app.userId == userId) {
11452                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11453                        mContext, app.info.packageName, app.info.flags);
11454            }
11455        }
11456        skipCurrentReceiverLocked(app);
11457    }
11458
11459    void skipCurrentReceiverLocked(ProcessRecord app) {
11460        for (BroadcastQueue queue : mBroadcastQueues) {
11461            queue.skipCurrentReceiverLocked(app);
11462        }
11463    }
11464
11465    /**
11466     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11467     * The application process will exit immediately after this call returns.
11468     * @param app object of the crashing app, null for the system server
11469     * @param crashInfo describing the exception
11470     */
11471    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11472        ProcessRecord r = findAppProcess(app, "Crash");
11473        final String processName = app == null ? "system_server"
11474                : (r == null ? "unknown" : r.processName);
11475
11476        handleApplicationCrashInner("crash", r, processName, crashInfo);
11477    }
11478
11479    /* Native crash reporting uses this inner version because it needs to be somewhat
11480     * decoupled from the AM-managed cleanup lifecycle
11481     */
11482    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11483            ApplicationErrorReport.CrashInfo crashInfo) {
11484        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11485                UserHandle.getUserId(Binder.getCallingUid()), processName,
11486                r == null ? -1 : r.info.flags,
11487                crashInfo.exceptionClassName,
11488                crashInfo.exceptionMessage,
11489                crashInfo.throwFileName,
11490                crashInfo.throwLineNumber);
11491
11492        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11493
11494        crashApplication(r, crashInfo);
11495    }
11496
11497    public void handleApplicationStrictModeViolation(
11498            IBinder app,
11499            int violationMask,
11500            StrictMode.ViolationInfo info) {
11501        ProcessRecord r = findAppProcess(app, "StrictMode");
11502        if (r == null) {
11503            return;
11504        }
11505
11506        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11507            Integer stackFingerprint = info.hashCode();
11508            boolean logIt = true;
11509            synchronized (mAlreadyLoggedViolatedStacks) {
11510                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11511                    logIt = false;
11512                    // TODO: sub-sample into EventLog for these, with
11513                    // the info.durationMillis?  Then we'd get
11514                    // the relative pain numbers, without logging all
11515                    // the stack traces repeatedly.  We'd want to do
11516                    // likewise in the client code, which also does
11517                    // dup suppression, before the Binder call.
11518                } else {
11519                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11520                        mAlreadyLoggedViolatedStacks.clear();
11521                    }
11522                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11523                }
11524            }
11525            if (logIt) {
11526                logStrictModeViolationToDropBox(r, info);
11527            }
11528        }
11529
11530        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11531            AppErrorResult result = new AppErrorResult();
11532            synchronized (this) {
11533                final long origId = Binder.clearCallingIdentity();
11534
11535                Message msg = Message.obtain();
11536                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11537                HashMap<String, Object> data = new HashMap<String, Object>();
11538                data.put("result", result);
11539                data.put("app", r);
11540                data.put("violationMask", violationMask);
11541                data.put("info", info);
11542                msg.obj = data;
11543                mHandler.sendMessage(msg);
11544
11545                Binder.restoreCallingIdentity(origId);
11546            }
11547            int res = result.get();
11548            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11549        }
11550    }
11551
11552    // Depending on the policy in effect, there could be a bunch of
11553    // these in quick succession so we try to batch these together to
11554    // minimize disk writes, number of dropbox entries, and maximize
11555    // compression, by having more fewer, larger records.
11556    private void logStrictModeViolationToDropBox(
11557            ProcessRecord process,
11558            StrictMode.ViolationInfo info) {
11559        if (info == null) {
11560            return;
11561        }
11562        final boolean isSystemApp = process == null ||
11563                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11564                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11565        final String processName = process == null ? "unknown" : process.processName;
11566        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11567        final DropBoxManager dbox = (DropBoxManager)
11568                mContext.getSystemService(Context.DROPBOX_SERVICE);
11569
11570        // Exit early if the dropbox isn't configured to accept this report type.
11571        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11572
11573        boolean bufferWasEmpty;
11574        boolean needsFlush;
11575        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11576        synchronized (sb) {
11577            bufferWasEmpty = sb.length() == 0;
11578            appendDropBoxProcessHeaders(process, processName, sb);
11579            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11580            sb.append("System-App: ").append(isSystemApp).append("\n");
11581            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11582            if (info.violationNumThisLoop != 0) {
11583                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11584            }
11585            if (info.numAnimationsRunning != 0) {
11586                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11587            }
11588            if (info.broadcastIntentAction != null) {
11589                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11590            }
11591            if (info.durationMillis != -1) {
11592                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11593            }
11594            if (info.numInstances != -1) {
11595                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11596            }
11597            if (info.tags != null) {
11598                for (String tag : info.tags) {
11599                    sb.append("Span-Tag: ").append(tag).append("\n");
11600                }
11601            }
11602            sb.append("\n");
11603            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11604                sb.append(info.crashInfo.stackTrace);
11605            }
11606            sb.append("\n");
11607
11608            // Only buffer up to ~64k.  Various logging bits truncate
11609            // things at 128k.
11610            needsFlush = (sb.length() > 64 * 1024);
11611        }
11612
11613        // Flush immediately if the buffer's grown too large, or this
11614        // is a non-system app.  Non-system apps are isolated with a
11615        // different tag & policy and not batched.
11616        //
11617        // Batching is useful during internal testing with
11618        // StrictMode settings turned up high.  Without batching,
11619        // thousands of separate files could be created on boot.
11620        if (!isSystemApp || needsFlush) {
11621            new Thread("Error dump: " + dropboxTag) {
11622                @Override
11623                public void run() {
11624                    String report;
11625                    synchronized (sb) {
11626                        report = sb.toString();
11627                        sb.delete(0, sb.length());
11628                        sb.trimToSize();
11629                    }
11630                    if (report.length() != 0) {
11631                        dbox.addText(dropboxTag, report);
11632                    }
11633                }
11634            }.start();
11635            return;
11636        }
11637
11638        // System app batching:
11639        if (!bufferWasEmpty) {
11640            // An existing dropbox-writing thread is outstanding, so
11641            // we don't need to start it up.  The existing thread will
11642            // catch the buffer appends we just did.
11643            return;
11644        }
11645
11646        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11647        // (After this point, we shouldn't access AMS internal data structures.)
11648        new Thread("Error dump: " + dropboxTag) {
11649            @Override
11650            public void run() {
11651                // 5 second sleep to let stacks arrive and be batched together
11652                try {
11653                    Thread.sleep(5000);  // 5 seconds
11654                } catch (InterruptedException e) {}
11655
11656                String errorReport;
11657                synchronized (mStrictModeBuffer) {
11658                    errorReport = mStrictModeBuffer.toString();
11659                    if (errorReport.length() == 0) {
11660                        return;
11661                    }
11662                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11663                    mStrictModeBuffer.trimToSize();
11664                }
11665                dbox.addText(dropboxTag, errorReport);
11666            }
11667        }.start();
11668    }
11669
11670    /**
11671     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11672     * @param app object of the crashing app, null for the system server
11673     * @param tag reported by the caller
11674     * @param system whether this wtf is coming from the system
11675     * @param crashInfo describing the context of the error
11676     * @return true if the process should exit immediately (WTF is fatal)
11677     */
11678    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11679            final ApplicationErrorReport.CrashInfo crashInfo) {
11680        final int callingUid = Binder.getCallingUid();
11681        final int callingPid = Binder.getCallingPid();
11682
11683        if (system) {
11684            // If this is coming from the system, we could very well have low-level
11685            // system locks held, so we want to do this all asynchronously.  And we
11686            // never want this to become fatal, so there is that too.
11687            mHandler.post(new Runnable() {
11688                @Override public void run() {
11689                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11690                }
11691            });
11692            return false;
11693        }
11694
11695        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11696                crashInfo);
11697
11698        if (r != null && r.pid != Process.myPid() &&
11699                Settings.Global.getInt(mContext.getContentResolver(),
11700                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11701            crashApplication(r, crashInfo);
11702            return true;
11703        } else {
11704            return false;
11705        }
11706    }
11707
11708    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11709            final ApplicationErrorReport.CrashInfo crashInfo) {
11710        final ProcessRecord r = findAppProcess(app, "WTF");
11711        final String processName = app == null ? "system_server"
11712                : (r == null ? "unknown" : r.processName);
11713
11714        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11715                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11716
11717        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11718
11719        return r;
11720    }
11721
11722    /**
11723     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11724     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11725     */
11726    private ProcessRecord findAppProcess(IBinder app, String reason) {
11727        if (app == null) {
11728            return null;
11729        }
11730
11731        synchronized (this) {
11732            final int NP = mProcessNames.getMap().size();
11733            for (int ip=0; ip<NP; ip++) {
11734                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11735                final int NA = apps.size();
11736                for (int ia=0; ia<NA; ia++) {
11737                    ProcessRecord p = apps.valueAt(ia);
11738                    if (p.thread != null && p.thread.asBinder() == app) {
11739                        return p;
11740                    }
11741                }
11742            }
11743
11744            Slog.w(TAG, "Can't find mystery application for " + reason
11745                    + " from pid=" + Binder.getCallingPid()
11746                    + " uid=" + Binder.getCallingUid() + ": " + app);
11747            return null;
11748        }
11749    }
11750
11751    /**
11752     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11753     * to append various headers to the dropbox log text.
11754     */
11755    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11756            StringBuilder sb) {
11757        // Watchdog thread ends up invoking this function (with
11758        // a null ProcessRecord) to add the stack file to dropbox.
11759        // Do not acquire a lock on this (am) in such cases, as it
11760        // could cause a potential deadlock, if and when watchdog
11761        // is invoked due to unavailability of lock on am and it
11762        // would prevent watchdog from killing system_server.
11763        if (process == null) {
11764            sb.append("Process: ").append(processName).append("\n");
11765            return;
11766        }
11767        // Note: ProcessRecord 'process' is guarded by the service
11768        // instance.  (notably process.pkgList, which could otherwise change
11769        // concurrently during execution of this method)
11770        synchronized (this) {
11771            sb.append("Process: ").append(processName).append("\n");
11772            int flags = process.info.flags;
11773            IPackageManager pm = AppGlobals.getPackageManager();
11774            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11775            for (int ip=0; ip<process.pkgList.size(); ip++) {
11776                String pkg = process.pkgList.keyAt(ip);
11777                sb.append("Package: ").append(pkg);
11778                try {
11779                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11780                    if (pi != null) {
11781                        sb.append(" v").append(pi.versionCode);
11782                        if (pi.versionName != null) {
11783                            sb.append(" (").append(pi.versionName).append(")");
11784                        }
11785                    }
11786                } catch (RemoteException e) {
11787                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11788                }
11789                sb.append("\n");
11790            }
11791        }
11792    }
11793
11794    private static String processClass(ProcessRecord process) {
11795        if (process == null || process.pid == MY_PID) {
11796            return "system_server";
11797        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11798            return "system_app";
11799        } else {
11800            return "data_app";
11801        }
11802    }
11803
11804    /**
11805     * Write a description of an error (crash, WTF, ANR) to the drop box.
11806     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11807     * @param process which caused the error, null means the system server
11808     * @param activity which triggered the error, null if unknown
11809     * @param parent activity related to the error, null if unknown
11810     * @param subject line related to the error, null if absent
11811     * @param report in long form describing the error, null if absent
11812     * @param logFile to include in the report, null if none
11813     * @param crashInfo giving an application stack trace, null if absent
11814     */
11815    public void addErrorToDropBox(String eventType,
11816            ProcessRecord process, String processName, ActivityRecord activity,
11817            ActivityRecord parent, String subject,
11818            final String report, final File logFile,
11819            final ApplicationErrorReport.CrashInfo crashInfo) {
11820        // NOTE -- this must never acquire the ActivityManagerService lock,
11821        // otherwise the watchdog may be prevented from resetting the system.
11822
11823        final String dropboxTag = processClass(process) + "_" + eventType;
11824        final DropBoxManager dbox = (DropBoxManager)
11825                mContext.getSystemService(Context.DROPBOX_SERVICE);
11826
11827        // Exit early if the dropbox isn't configured to accept this report type.
11828        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11829
11830        final StringBuilder sb = new StringBuilder(1024);
11831        appendDropBoxProcessHeaders(process, processName, sb);
11832        if (activity != null) {
11833            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11834        }
11835        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11836            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11837        }
11838        if (parent != null && parent != activity) {
11839            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11840        }
11841        if (subject != null) {
11842            sb.append("Subject: ").append(subject).append("\n");
11843        }
11844        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11845        if (Debug.isDebuggerConnected()) {
11846            sb.append("Debugger: Connected\n");
11847        }
11848        sb.append("\n");
11849
11850        // Do the rest in a worker thread to avoid blocking the caller on I/O
11851        // (After this point, we shouldn't access AMS internal data structures.)
11852        Thread worker = new Thread("Error dump: " + dropboxTag) {
11853            @Override
11854            public void run() {
11855                if (report != null) {
11856                    sb.append(report);
11857                }
11858                if (logFile != null) {
11859                    try {
11860                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11861                                    "\n\n[[TRUNCATED]]"));
11862                    } catch (IOException e) {
11863                        Slog.e(TAG, "Error reading " + logFile, e);
11864                    }
11865                }
11866                if (crashInfo != null && crashInfo.stackTrace != null) {
11867                    sb.append(crashInfo.stackTrace);
11868                }
11869
11870                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11871                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11872                if (lines > 0) {
11873                    sb.append("\n");
11874
11875                    // Merge several logcat streams, and take the last N lines
11876                    InputStreamReader input = null;
11877                    try {
11878                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11879                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11880                                "-b", "crash",
11881                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11882
11883                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11884                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11885                        input = new InputStreamReader(logcat.getInputStream());
11886
11887                        int num;
11888                        char[] buf = new char[8192];
11889                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11890                    } catch (IOException e) {
11891                        Slog.e(TAG, "Error running logcat", e);
11892                    } finally {
11893                        if (input != null) try { input.close(); } catch (IOException e) {}
11894                    }
11895                }
11896
11897                dbox.addText(dropboxTag, sb.toString());
11898            }
11899        };
11900
11901        if (process == null) {
11902            // If process is null, we are being called from some internal code
11903            // and may be about to die -- run this synchronously.
11904            worker.run();
11905        } else {
11906            worker.start();
11907        }
11908    }
11909
11910    /**
11911     * Bring up the "unexpected error" dialog box for a crashing app.
11912     * Deal with edge cases (intercepts from instrumented applications,
11913     * ActivityController, error intent receivers, that sort of thing).
11914     * @param r the application crashing
11915     * @param crashInfo describing the failure
11916     */
11917    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11918        long timeMillis = System.currentTimeMillis();
11919        String shortMsg = crashInfo.exceptionClassName;
11920        String longMsg = crashInfo.exceptionMessage;
11921        String stackTrace = crashInfo.stackTrace;
11922        if (shortMsg != null && longMsg != null) {
11923            longMsg = shortMsg + ": " + longMsg;
11924        } else if (shortMsg != null) {
11925            longMsg = shortMsg;
11926        }
11927
11928        AppErrorResult result = new AppErrorResult();
11929        synchronized (this) {
11930            if (mController != null) {
11931                try {
11932                    String name = r != null ? r.processName : null;
11933                    int pid = r != null ? r.pid : Binder.getCallingPid();
11934                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11935                    if (!mController.appCrashed(name, pid,
11936                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11937                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11938                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11939                            Slog.w(TAG, "Skip killing native crashed app " + name
11940                                    + "(" + pid + ") during testing");
11941                        } else {
11942                            Slog.w(TAG, "Force-killing crashed app " + name
11943                                    + " at watcher's request");
11944                            if (r != null) {
11945                                r.kill("crash", true);
11946                            } else {
11947                                // Huh.
11948                                Process.killProcess(pid);
11949                                Process.killProcessGroup(uid, pid);
11950                            }
11951                        }
11952                        return;
11953                    }
11954                } catch (RemoteException e) {
11955                    mController = null;
11956                    Watchdog.getInstance().setActivityController(null);
11957                }
11958            }
11959
11960            final long origId = Binder.clearCallingIdentity();
11961
11962            // If this process is running instrumentation, finish it.
11963            if (r != null && r.instrumentationClass != null) {
11964                Slog.w(TAG, "Error in app " + r.processName
11965                      + " running instrumentation " + r.instrumentationClass + ":");
11966                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11967                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11968                Bundle info = new Bundle();
11969                info.putString("shortMsg", shortMsg);
11970                info.putString("longMsg", longMsg);
11971                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11972                Binder.restoreCallingIdentity(origId);
11973                return;
11974            }
11975
11976            // If we can't identify the process or it's already exceeded its crash quota,
11977            // quit right away without showing a crash dialog.
11978            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11979                Binder.restoreCallingIdentity(origId);
11980                return;
11981            }
11982
11983            Message msg = Message.obtain();
11984            msg.what = SHOW_ERROR_MSG;
11985            HashMap data = new HashMap();
11986            data.put("result", result);
11987            data.put("app", r);
11988            msg.obj = data;
11989            mHandler.sendMessage(msg);
11990
11991            Binder.restoreCallingIdentity(origId);
11992        }
11993
11994        int res = result.get();
11995
11996        Intent appErrorIntent = null;
11997        synchronized (this) {
11998            if (r != null && !r.isolated) {
11999                // XXX Can't keep track of crash time for isolated processes,
12000                // since they don't have a persistent identity.
12001                mProcessCrashTimes.put(r.info.processName, r.uid,
12002                        SystemClock.uptimeMillis());
12003            }
12004            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12005                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12006            }
12007        }
12008
12009        if (appErrorIntent != null) {
12010            try {
12011                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12012            } catch (ActivityNotFoundException e) {
12013                Slog.w(TAG, "bug report receiver dissappeared", e);
12014            }
12015        }
12016    }
12017
12018    Intent createAppErrorIntentLocked(ProcessRecord r,
12019            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12020        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12021        if (report == null) {
12022            return null;
12023        }
12024        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12025        result.setComponent(r.errorReportReceiver);
12026        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12027        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12028        return result;
12029    }
12030
12031    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12032            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12033        if (r.errorReportReceiver == null) {
12034            return null;
12035        }
12036
12037        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12038            return null;
12039        }
12040
12041        ApplicationErrorReport report = new ApplicationErrorReport();
12042        report.packageName = r.info.packageName;
12043        report.installerPackageName = r.errorReportReceiver.getPackageName();
12044        report.processName = r.processName;
12045        report.time = timeMillis;
12046        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12047
12048        if (r.crashing || r.forceCrashReport) {
12049            report.type = ApplicationErrorReport.TYPE_CRASH;
12050            report.crashInfo = crashInfo;
12051        } else if (r.notResponding) {
12052            report.type = ApplicationErrorReport.TYPE_ANR;
12053            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12054
12055            report.anrInfo.activity = r.notRespondingReport.tag;
12056            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12057            report.anrInfo.info = r.notRespondingReport.longMsg;
12058        }
12059
12060        return report;
12061    }
12062
12063    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12064        enforceNotIsolatedCaller("getProcessesInErrorState");
12065        // assume our apps are happy - lazy create the list
12066        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12067
12068        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12069                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12070        int userId = UserHandle.getUserId(Binder.getCallingUid());
12071
12072        synchronized (this) {
12073
12074            // iterate across all processes
12075            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12076                ProcessRecord app = mLruProcesses.get(i);
12077                if (!allUsers && app.userId != userId) {
12078                    continue;
12079                }
12080                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12081                    // This one's in trouble, so we'll generate a report for it
12082                    // crashes are higher priority (in case there's a crash *and* an anr)
12083                    ActivityManager.ProcessErrorStateInfo report = null;
12084                    if (app.crashing) {
12085                        report = app.crashingReport;
12086                    } else if (app.notResponding) {
12087                        report = app.notRespondingReport;
12088                    }
12089
12090                    if (report != null) {
12091                        if (errList == null) {
12092                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12093                        }
12094                        errList.add(report);
12095                    } else {
12096                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12097                                " crashing = " + app.crashing +
12098                                " notResponding = " + app.notResponding);
12099                    }
12100                }
12101            }
12102        }
12103
12104        return errList;
12105    }
12106
12107    static int procStateToImportance(int procState, int memAdj,
12108            ActivityManager.RunningAppProcessInfo currApp) {
12109        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12110        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12111            currApp.lru = memAdj;
12112        } else {
12113            currApp.lru = 0;
12114        }
12115        return imp;
12116    }
12117
12118    private void fillInProcMemInfo(ProcessRecord app,
12119            ActivityManager.RunningAppProcessInfo outInfo) {
12120        outInfo.pid = app.pid;
12121        outInfo.uid = app.info.uid;
12122        if (mHeavyWeightProcess == app) {
12123            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12124        }
12125        if (app.persistent) {
12126            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12127        }
12128        if (app.activities.size() > 0) {
12129            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12130        }
12131        outInfo.lastTrimLevel = app.trimMemoryLevel;
12132        int adj = app.curAdj;
12133        int procState = app.curProcState;
12134        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12135        outInfo.importanceReasonCode = app.adjTypeCode;
12136        outInfo.processState = app.curProcState;
12137    }
12138
12139    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12140        enforceNotIsolatedCaller("getRunningAppProcesses");
12141        // Lazy instantiation of list
12142        List<ActivityManager.RunningAppProcessInfo> runList = null;
12143        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12144                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12145        int userId = UserHandle.getUserId(Binder.getCallingUid());
12146        synchronized (this) {
12147            // Iterate across all processes
12148            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12149                ProcessRecord app = mLruProcesses.get(i);
12150                if (!allUsers && app.userId != userId) {
12151                    continue;
12152                }
12153                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12154                    // Generate process state info for running application
12155                    ActivityManager.RunningAppProcessInfo currApp =
12156                        new ActivityManager.RunningAppProcessInfo(app.processName,
12157                                app.pid, app.getPackageList());
12158                    fillInProcMemInfo(app, currApp);
12159                    if (app.adjSource instanceof ProcessRecord) {
12160                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12161                        currApp.importanceReasonImportance =
12162                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12163                                        app.adjSourceProcState);
12164                    } else if (app.adjSource instanceof ActivityRecord) {
12165                        ActivityRecord r = (ActivityRecord)app.adjSource;
12166                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12167                    }
12168                    if (app.adjTarget instanceof ComponentName) {
12169                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12170                    }
12171                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12172                    //        + " lru=" + currApp.lru);
12173                    if (runList == null) {
12174                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12175                    }
12176                    runList.add(currApp);
12177                }
12178            }
12179        }
12180        return runList;
12181    }
12182
12183    public List<ApplicationInfo> getRunningExternalApplications() {
12184        enforceNotIsolatedCaller("getRunningExternalApplications");
12185        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12186        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12187        if (runningApps != null && runningApps.size() > 0) {
12188            Set<String> extList = new HashSet<String>();
12189            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12190                if (app.pkgList != null) {
12191                    for (String pkg : app.pkgList) {
12192                        extList.add(pkg);
12193                    }
12194                }
12195            }
12196            IPackageManager pm = AppGlobals.getPackageManager();
12197            for (String pkg : extList) {
12198                try {
12199                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12200                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12201                        retList.add(info);
12202                    }
12203                } catch (RemoteException e) {
12204                }
12205            }
12206        }
12207        return retList;
12208    }
12209
12210    @Override
12211    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12212        enforceNotIsolatedCaller("getMyMemoryState");
12213        synchronized (this) {
12214            ProcessRecord proc;
12215            synchronized (mPidsSelfLocked) {
12216                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12217            }
12218            fillInProcMemInfo(proc, outInfo);
12219        }
12220    }
12221
12222    @Override
12223    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12224        if (checkCallingPermission(android.Manifest.permission.DUMP)
12225                != PackageManager.PERMISSION_GRANTED) {
12226            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12227                    + Binder.getCallingPid()
12228                    + ", uid=" + Binder.getCallingUid()
12229                    + " without permission "
12230                    + android.Manifest.permission.DUMP);
12231            return;
12232        }
12233
12234        boolean dumpAll = false;
12235        boolean dumpClient = false;
12236        String dumpPackage = null;
12237
12238        int opti = 0;
12239        while (opti < args.length) {
12240            String opt = args[opti];
12241            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12242                break;
12243            }
12244            opti++;
12245            if ("-a".equals(opt)) {
12246                dumpAll = true;
12247            } else if ("-c".equals(opt)) {
12248                dumpClient = true;
12249            } else if ("-h".equals(opt)) {
12250                pw.println("Activity manager dump options:");
12251                pw.println("  [-a] [-c] [-h] [cmd] ...");
12252                pw.println("  cmd may be one of:");
12253                pw.println("    a[ctivities]: activity stack state");
12254                pw.println("    r[recents]: recent activities state");
12255                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12256                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12257                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12258                pw.println("    o[om]: out of memory management");
12259                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12260                pw.println("    provider [COMP_SPEC]: provider client-side state");
12261                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12262                pw.println("    service [COMP_SPEC]: service client-side state");
12263                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12264                pw.println("    all: dump all activities");
12265                pw.println("    top: dump the top activity");
12266                pw.println("    write: write all pending state to storage");
12267                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12268                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12269                pw.println("    a partial substring in a component name, a");
12270                pw.println("    hex object identifier.");
12271                pw.println("  -a: include all available server state.");
12272                pw.println("  -c: include client state.");
12273                return;
12274            } else {
12275                pw.println("Unknown argument: " + opt + "; use -h for help");
12276            }
12277        }
12278
12279        long origId = Binder.clearCallingIdentity();
12280        boolean more = false;
12281        // Is the caller requesting to dump a particular piece of data?
12282        if (opti < args.length) {
12283            String cmd = args[opti];
12284            opti++;
12285            if ("activities".equals(cmd) || "a".equals(cmd)) {
12286                synchronized (this) {
12287                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12288                }
12289            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12290                synchronized (this) {
12291                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12292                }
12293            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12294                String[] newArgs;
12295                String name;
12296                if (opti >= args.length) {
12297                    name = null;
12298                    newArgs = EMPTY_STRING_ARRAY;
12299                } else {
12300                    name = args[opti];
12301                    opti++;
12302                    newArgs = new String[args.length - opti];
12303                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12304                            args.length - opti);
12305                }
12306                synchronized (this) {
12307                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12308                }
12309            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12310                String[] newArgs;
12311                String name;
12312                if (opti >= args.length) {
12313                    name = null;
12314                    newArgs = EMPTY_STRING_ARRAY;
12315                } else {
12316                    name = args[opti];
12317                    opti++;
12318                    newArgs = new String[args.length - opti];
12319                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12320                            args.length - opti);
12321                }
12322                synchronized (this) {
12323                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12324                }
12325            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12326                String[] newArgs;
12327                String name;
12328                if (opti >= args.length) {
12329                    name = null;
12330                    newArgs = EMPTY_STRING_ARRAY;
12331                } else {
12332                    name = args[opti];
12333                    opti++;
12334                    newArgs = new String[args.length - opti];
12335                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12336                            args.length - opti);
12337                }
12338                synchronized (this) {
12339                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12340                }
12341            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12342                synchronized (this) {
12343                    dumpOomLocked(fd, pw, args, opti, true);
12344                }
12345            } else if ("provider".equals(cmd)) {
12346                String[] newArgs;
12347                String name;
12348                if (opti >= args.length) {
12349                    name = null;
12350                    newArgs = EMPTY_STRING_ARRAY;
12351                } else {
12352                    name = args[opti];
12353                    opti++;
12354                    newArgs = new String[args.length - opti];
12355                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12356                }
12357                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12358                    pw.println("No providers match: " + name);
12359                    pw.println("Use -h for help.");
12360                }
12361            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12362                synchronized (this) {
12363                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12364                }
12365            } else if ("service".equals(cmd)) {
12366                String[] newArgs;
12367                String name;
12368                if (opti >= args.length) {
12369                    name = null;
12370                    newArgs = EMPTY_STRING_ARRAY;
12371                } else {
12372                    name = args[opti];
12373                    opti++;
12374                    newArgs = new String[args.length - opti];
12375                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12376                            args.length - opti);
12377                }
12378                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12379                    pw.println("No services match: " + name);
12380                    pw.println("Use -h for help.");
12381                }
12382            } else if ("package".equals(cmd)) {
12383                String[] newArgs;
12384                if (opti >= args.length) {
12385                    pw.println("package: no package name specified");
12386                    pw.println("Use -h for help.");
12387                } else {
12388                    dumpPackage = args[opti];
12389                    opti++;
12390                    newArgs = new String[args.length - opti];
12391                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12392                            args.length - opti);
12393                    args = newArgs;
12394                    opti = 0;
12395                    more = true;
12396                }
12397            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12398                synchronized (this) {
12399                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12400                }
12401            } else if ("write".equals(cmd)) {
12402                mTaskPersister.flush();
12403                pw.println("All tasks persisted.");
12404                return;
12405            } else {
12406                // Dumping a single activity?
12407                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12408                    pw.println("Bad activity command, or no activities match: " + cmd);
12409                    pw.println("Use -h for help.");
12410                }
12411            }
12412            if (!more) {
12413                Binder.restoreCallingIdentity(origId);
12414                return;
12415            }
12416        }
12417
12418        // No piece of data specified, dump everything.
12419        synchronized (this) {
12420            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12421            pw.println();
12422            if (dumpAll) {
12423                pw.println("-------------------------------------------------------------------------------");
12424            }
12425            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12426            pw.println();
12427            if (dumpAll) {
12428                pw.println("-------------------------------------------------------------------------------");
12429            }
12430            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12431            pw.println();
12432            if (dumpAll) {
12433                pw.println("-------------------------------------------------------------------------------");
12434            }
12435            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12436            pw.println();
12437            if (dumpAll) {
12438                pw.println("-------------------------------------------------------------------------------");
12439            }
12440            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12441            pw.println();
12442            if (dumpAll) {
12443                pw.println("-------------------------------------------------------------------------------");
12444            }
12445            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12446            pw.println();
12447            if (dumpAll) {
12448                pw.println("-------------------------------------------------------------------------------");
12449            }
12450            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12451        }
12452        Binder.restoreCallingIdentity(origId);
12453    }
12454
12455    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12456            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12457        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12458
12459        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12460                dumpPackage);
12461        boolean needSep = printedAnything;
12462
12463        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12464                dumpPackage, needSep, "  mFocusedActivity: ");
12465        if (printed) {
12466            printedAnything = true;
12467            needSep = false;
12468        }
12469
12470        if (dumpPackage == null) {
12471            if (needSep) {
12472                pw.println();
12473            }
12474            needSep = true;
12475            printedAnything = true;
12476            mStackSupervisor.dump(pw, "  ");
12477        }
12478
12479        if (!printedAnything) {
12480            pw.println("  (nothing)");
12481        }
12482    }
12483
12484    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12485            int opti, boolean dumpAll, String dumpPackage) {
12486        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12487
12488        boolean printedAnything = false;
12489
12490        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12491            boolean printedHeader = false;
12492
12493            final int N = mRecentTasks.size();
12494            for (int i=0; i<N; i++) {
12495                TaskRecord tr = mRecentTasks.get(i);
12496                if (dumpPackage != null) {
12497                    if (tr.realActivity == null ||
12498                            !dumpPackage.equals(tr.realActivity)) {
12499                        continue;
12500                    }
12501                }
12502                if (!printedHeader) {
12503                    pw.println("  Recent tasks:");
12504                    printedHeader = true;
12505                    printedAnything = true;
12506                }
12507                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12508                        pw.println(tr);
12509                if (dumpAll) {
12510                    mRecentTasks.get(i).dump(pw, "    ");
12511                }
12512            }
12513        }
12514
12515        if (!printedAnything) {
12516            pw.println("  (nothing)");
12517        }
12518    }
12519
12520    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12521            int opti, boolean dumpAll, String dumpPackage) {
12522        boolean needSep = false;
12523        boolean printedAnything = false;
12524        int numPers = 0;
12525
12526        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12527
12528        if (dumpAll) {
12529            final int NP = mProcessNames.getMap().size();
12530            for (int ip=0; ip<NP; ip++) {
12531                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12532                final int NA = procs.size();
12533                for (int ia=0; ia<NA; ia++) {
12534                    ProcessRecord r = procs.valueAt(ia);
12535                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12536                        continue;
12537                    }
12538                    if (!needSep) {
12539                        pw.println("  All known processes:");
12540                        needSep = true;
12541                        printedAnything = true;
12542                    }
12543                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12544                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12545                        pw.print(" "); pw.println(r);
12546                    r.dump(pw, "    ");
12547                    if (r.persistent) {
12548                        numPers++;
12549                    }
12550                }
12551            }
12552        }
12553
12554        if (mIsolatedProcesses.size() > 0) {
12555            boolean printed = false;
12556            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12557                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12558                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12559                    continue;
12560                }
12561                if (!printed) {
12562                    if (needSep) {
12563                        pw.println();
12564                    }
12565                    pw.println("  Isolated process list (sorted by uid):");
12566                    printedAnything = true;
12567                    printed = true;
12568                    needSep = true;
12569                }
12570                pw.println(String.format("%sIsolated #%2d: %s",
12571                        "    ", i, r.toString()));
12572            }
12573        }
12574
12575        if (mLruProcesses.size() > 0) {
12576            if (needSep) {
12577                pw.println();
12578            }
12579            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12580                    pw.print(" total, non-act at ");
12581                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12582                    pw.print(", non-svc at ");
12583                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12584                    pw.println("):");
12585            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12586            needSep = true;
12587            printedAnything = true;
12588        }
12589
12590        if (dumpAll || dumpPackage != null) {
12591            synchronized (mPidsSelfLocked) {
12592                boolean printed = false;
12593                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12594                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12595                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12596                        continue;
12597                    }
12598                    if (!printed) {
12599                        if (needSep) pw.println();
12600                        needSep = true;
12601                        pw.println("  PID mappings:");
12602                        printed = true;
12603                        printedAnything = true;
12604                    }
12605                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12606                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12607                }
12608            }
12609        }
12610
12611        if (mForegroundProcesses.size() > 0) {
12612            synchronized (mPidsSelfLocked) {
12613                boolean printed = false;
12614                for (int i=0; i<mForegroundProcesses.size(); i++) {
12615                    ProcessRecord r = mPidsSelfLocked.get(
12616                            mForegroundProcesses.valueAt(i).pid);
12617                    if (dumpPackage != null && (r == null
12618                            || !r.pkgList.containsKey(dumpPackage))) {
12619                        continue;
12620                    }
12621                    if (!printed) {
12622                        if (needSep) pw.println();
12623                        needSep = true;
12624                        pw.println("  Foreground Processes:");
12625                        printed = true;
12626                        printedAnything = true;
12627                    }
12628                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12629                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12630                }
12631            }
12632        }
12633
12634        if (mPersistentStartingProcesses.size() > 0) {
12635            if (needSep) pw.println();
12636            needSep = true;
12637            printedAnything = true;
12638            pw.println("  Persisent processes that are starting:");
12639            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12640                    "Starting Norm", "Restarting PERS", dumpPackage);
12641        }
12642
12643        if (mRemovedProcesses.size() > 0) {
12644            if (needSep) pw.println();
12645            needSep = true;
12646            printedAnything = true;
12647            pw.println("  Processes that are being removed:");
12648            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12649                    "Removed Norm", "Removed PERS", dumpPackage);
12650        }
12651
12652        if (mProcessesOnHold.size() > 0) {
12653            if (needSep) pw.println();
12654            needSep = true;
12655            printedAnything = true;
12656            pw.println("  Processes that are on old until the system is ready:");
12657            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12658                    "OnHold Norm", "OnHold PERS", dumpPackage);
12659        }
12660
12661        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12662
12663        if (mProcessCrashTimes.getMap().size() > 0) {
12664            boolean printed = false;
12665            long now = SystemClock.uptimeMillis();
12666            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12667            final int NP = pmap.size();
12668            for (int ip=0; ip<NP; ip++) {
12669                String pname = pmap.keyAt(ip);
12670                SparseArray<Long> uids = pmap.valueAt(ip);
12671                final int N = uids.size();
12672                for (int i=0; i<N; i++) {
12673                    int puid = uids.keyAt(i);
12674                    ProcessRecord r = mProcessNames.get(pname, puid);
12675                    if (dumpPackage != null && (r == null
12676                            || !r.pkgList.containsKey(dumpPackage))) {
12677                        continue;
12678                    }
12679                    if (!printed) {
12680                        if (needSep) pw.println();
12681                        needSep = true;
12682                        pw.println("  Time since processes crashed:");
12683                        printed = true;
12684                        printedAnything = true;
12685                    }
12686                    pw.print("    Process "); pw.print(pname);
12687                            pw.print(" uid "); pw.print(puid);
12688                            pw.print(": last crashed ");
12689                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12690                            pw.println(" ago");
12691                }
12692            }
12693        }
12694
12695        if (mBadProcesses.getMap().size() > 0) {
12696            boolean printed = false;
12697            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12698            final int NP = pmap.size();
12699            for (int ip=0; ip<NP; ip++) {
12700                String pname = pmap.keyAt(ip);
12701                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12702                final int N = uids.size();
12703                for (int i=0; i<N; i++) {
12704                    int puid = uids.keyAt(i);
12705                    ProcessRecord r = mProcessNames.get(pname, puid);
12706                    if (dumpPackage != null && (r == null
12707                            || !r.pkgList.containsKey(dumpPackage))) {
12708                        continue;
12709                    }
12710                    if (!printed) {
12711                        if (needSep) pw.println();
12712                        needSep = true;
12713                        pw.println("  Bad processes:");
12714                        printedAnything = true;
12715                    }
12716                    BadProcessInfo info = uids.valueAt(i);
12717                    pw.print("    Bad process "); pw.print(pname);
12718                            pw.print(" uid "); pw.print(puid);
12719                            pw.print(": crashed at time "); pw.println(info.time);
12720                    if (info.shortMsg != null) {
12721                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12722                    }
12723                    if (info.longMsg != null) {
12724                        pw.print("      Long msg: "); pw.println(info.longMsg);
12725                    }
12726                    if (info.stack != null) {
12727                        pw.println("      Stack:");
12728                        int lastPos = 0;
12729                        for (int pos=0; pos<info.stack.length(); pos++) {
12730                            if (info.stack.charAt(pos) == '\n') {
12731                                pw.print("        ");
12732                                pw.write(info.stack, lastPos, pos-lastPos);
12733                                pw.println();
12734                                lastPos = pos+1;
12735                            }
12736                        }
12737                        if (lastPos < info.stack.length()) {
12738                            pw.print("        ");
12739                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12740                            pw.println();
12741                        }
12742                    }
12743                }
12744            }
12745        }
12746
12747        if (dumpPackage == null) {
12748            pw.println();
12749            needSep = false;
12750            pw.println("  mStartedUsers:");
12751            for (int i=0; i<mStartedUsers.size(); i++) {
12752                UserStartedState uss = mStartedUsers.valueAt(i);
12753                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12754                        pw.print(": "); uss.dump("", pw);
12755            }
12756            pw.print("  mStartedUserArray: [");
12757            for (int i=0; i<mStartedUserArray.length; i++) {
12758                if (i > 0) pw.print(", ");
12759                pw.print(mStartedUserArray[i]);
12760            }
12761            pw.println("]");
12762            pw.print("  mUserLru: [");
12763            for (int i=0; i<mUserLru.size(); i++) {
12764                if (i > 0) pw.print(", ");
12765                pw.print(mUserLru.get(i));
12766            }
12767            pw.println("]");
12768            if (dumpAll) {
12769                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12770            }
12771            synchronized (mUserProfileGroupIdsSelfLocked) {
12772                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12773                    pw.println("  mUserProfileGroupIds:");
12774                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12775                        pw.print("    User #");
12776                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12777                        pw.print(" -> profile #");
12778                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12779                    }
12780                }
12781            }
12782        }
12783        if (mHomeProcess != null && (dumpPackage == null
12784                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12785            if (needSep) {
12786                pw.println();
12787                needSep = false;
12788            }
12789            pw.println("  mHomeProcess: " + mHomeProcess);
12790        }
12791        if (mPreviousProcess != null && (dumpPackage == null
12792                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12793            if (needSep) {
12794                pw.println();
12795                needSep = false;
12796            }
12797            pw.println("  mPreviousProcess: " + mPreviousProcess);
12798        }
12799        if (dumpAll) {
12800            StringBuilder sb = new StringBuilder(128);
12801            sb.append("  mPreviousProcessVisibleTime: ");
12802            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12803            pw.println(sb);
12804        }
12805        if (mHeavyWeightProcess != null && (dumpPackage == null
12806                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12807            if (needSep) {
12808                pw.println();
12809                needSep = false;
12810            }
12811            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12812        }
12813        if (dumpPackage == null) {
12814            pw.println("  mConfiguration: " + mConfiguration);
12815        }
12816        if (dumpAll) {
12817            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12818            if (mCompatModePackages.getPackages().size() > 0) {
12819                boolean printed = false;
12820                for (Map.Entry<String, Integer> entry
12821                        : mCompatModePackages.getPackages().entrySet()) {
12822                    String pkg = entry.getKey();
12823                    int mode = entry.getValue();
12824                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12825                        continue;
12826                    }
12827                    if (!printed) {
12828                        pw.println("  mScreenCompatPackages:");
12829                        printed = true;
12830                    }
12831                    pw.print("    "); pw.print(pkg); pw.print(": ");
12832                            pw.print(mode); pw.println();
12833                }
12834            }
12835        }
12836        if (dumpPackage == null) {
12837            if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) {
12838                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12839                        + " mLockScreenShown " + lockScreenShownToString());
12840            }
12841            if (mShuttingDown || mRunningVoice) {
12842                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12843            }
12844        }
12845        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12846                || mOrigWaitForDebugger) {
12847            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12848                    || dumpPackage.equals(mOrigDebugApp)) {
12849                if (needSep) {
12850                    pw.println();
12851                    needSep = false;
12852                }
12853                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12854                        + " mDebugTransient=" + mDebugTransient
12855                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12856            }
12857        }
12858        if (mOpenGlTraceApp != null) {
12859            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12860                if (needSep) {
12861                    pw.println();
12862                    needSep = false;
12863                }
12864                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12865            }
12866        }
12867        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12868                || mProfileFd != null) {
12869            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12870                if (needSep) {
12871                    pw.println();
12872                    needSep = false;
12873                }
12874                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12875                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12876                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12877                        + mAutoStopProfiler);
12878                pw.println("  mProfileType=" + mProfileType);
12879            }
12880        }
12881        if (dumpPackage == null) {
12882            if (mAlwaysFinishActivities || mController != null) {
12883                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12884                        + " mController=" + mController);
12885            }
12886            if (dumpAll) {
12887                pw.println("  Total persistent processes: " + numPers);
12888                pw.println("  mProcessesReady=" + mProcessesReady
12889                        + " mSystemReady=" + mSystemReady
12890                        + " mBooted=" + mBooted
12891                        + " mFactoryTest=" + mFactoryTest);
12892                pw.println("  mBooting=" + mBooting
12893                        + " mCallFinishBooting=" + mCallFinishBooting
12894                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12895                pw.print("  mLastPowerCheckRealtime=");
12896                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12897                        pw.println("");
12898                pw.print("  mLastPowerCheckUptime=");
12899                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12900                        pw.println("");
12901                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12902                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12903                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12904                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12905                        + " (" + mLruProcesses.size() + " total)"
12906                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12907                        + " mNumServiceProcs=" + mNumServiceProcs
12908                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12909                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12910                        + " mLastMemoryLevel" + mLastMemoryLevel
12911                        + " mLastNumProcesses" + mLastNumProcesses);
12912                long now = SystemClock.uptimeMillis();
12913                pw.print("  mLastIdleTime=");
12914                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12915                        pw.print(" mLowRamSinceLastIdle=");
12916                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12917                        pw.println();
12918            }
12919        }
12920
12921        if (!printedAnything) {
12922            pw.println("  (nothing)");
12923        }
12924    }
12925
12926    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12927            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12928        if (mProcessesToGc.size() > 0) {
12929            boolean printed = false;
12930            long now = SystemClock.uptimeMillis();
12931            for (int i=0; i<mProcessesToGc.size(); i++) {
12932                ProcessRecord proc = mProcessesToGc.get(i);
12933                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12934                    continue;
12935                }
12936                if (!printed) {
12937                    if (needSep) pw.println();
12938                    needSep = true;
12939                    pw.println("  Processes that are waiting to GC:");
12940                    printed = true;
12941                }
12942                pw.print("    Process "); pw.println(proc);
12943                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12944                        pw.print(", last gced=");
12945                        pw.print(now-proc.lastRequestedGc);
12946                        pw.print(" ms ago, last lowMem=");
12947                        pw.print(now-proc.lastLowMemory);
12948                        pw.println(" ms ago");
12949
12950            }
12951        }
12952        return needSep;
12953    }
12954
12955    void printOomLevel(PrintWriter pw, String name, int adj) {
12956        pw.print("    ");
12957        if (adj >= 0) {
12958            pw.print(' ');
12959            if (adj < 10) pw.print(' ');
12960        } else {
12961            if (adj > -10) pw.print(' ');
12962        }
12963        pw.print(adj);
12964        pw.print(": ");
12965        pw.print(name);
12966        pw.print(" (");
12967        pw.print(mProcessList.getMemLevel(adj)/1024);
12968        pw.println(" kB)");
12969    }
12970
12971    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12972            int opti, boolean dumpAll) {
12973        boolean needSep = false;
12974
12975        if (mLruProcesses.size() > 0) {
12976            if (needSep) pw.println();
12977            needSep = true;
12978            pw.println("  OOM levels:");
12979            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12980            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12981            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12982            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12983            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12984            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12985            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12986            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12987            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12988            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12989            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12990            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12991            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12992            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12993
12994            if (needSep) pw.println();
12995            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12996                    pw.print(" total, non-act at ");
12997                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12998                    pw.print(", non-svc at ");
12999                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13000                    pw.println("):");
13001            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13002            needSep = true;
13003        }
13004
13005        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13006
13007        pw.println();
13008        pw.println("  mHomeProcess: " + mHomeProcess);
13009        pw.println("  mPreviousProcess: " + mPreviousProcess);
13010        if (mHeavyWeightProcess != null) {
13011            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13012        }
13013
13014        return true;
13015    }
13016
13017    /**
13018     * There are three ways to call this:
13019     *  - no provider specified: dump all the providers
13020     *  - a flattened component name that matched an existing provider was specified as the
13021     *    first arg: dump that one provider
13022     *  - the first arg isn't the flattened component name of an existing provider:
13023     *    dump all providers whose component contains the first arg as a substring
13024     */
13025    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13026            int opti, boolean dumpAll) {
13027        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13028    }
13029
13030    static class ItemMatcher {
13031        ArrayList<ComponentName> components;
13032        ArrayList<String> strings;
13033        ArrayList<Integer> objects;
13034        boolean all;
13035
13036        ItemMatcher() {
13037            all = true;
13038        }
13039
13040        void build(String name) {
13041            ComponentName componentName = ComponentName.unflattenFromString(name);
13042            if (componentName != null) {
13043                if (components == null) {
13044                    components = new ArrayList<ComponentName>();
13045                }
13046                components.add(componentName);
13047                all = false;
13048            } else {
13049                int objectId = 0;
13050                // Not a '/' separated full component name; maybe an object ID?
13051                try {
13052                    objectId = Integer.parseInt(name, 16);
13053                    if (objects == null) {
13054                        objects = new ArrayList<Integer>();
13055                    }
13056                    objects.add(objectId);
13057                    all = false;
13058                } catch (RuntimeException e) {
13059                    // Not an integer; just do string match.
13060                    if (strings == null) {
13061                        strings = new ArrayList<String>();
13062                    }
13063                    strings.add(name);
13064                    all = false;
13065                }
13066            }
13067        }
13068
13069        int build(String[] args, int opti) {
13070            for (; opti<args.length; opti++) {
13071                String name = args[opti];
13072                if ("--".equals(name)) {
13073                    return opti+1;
13074                }
13075                build(name);
13076            }
13077            return opti;
13078        }
13079
13080        boolean match(Object object, ComponentName comp) {
13081            if (all) {
13082                return true;
13083            }
13084            if (components != null) {
13085                for (int i=0; i<components.size(); i++) {
13086                    if (components.get(i).equals(comp)) {
13087                        return true;
13088                    }
13089                }
13090            }
13091            if (objects != null) {
13092                for (int i=0; i<objects.size(); i++) {
13093                    if (System.identityHashCode(object) == objects.get(i)) {
13094                        return true;
13095                    }
13096                }
13097            }
13098            if (strings != null) {
13099                String flat = comp.flattenToString();
13100                for (int i=0; i<strings.size(); i++) {
13101                    if (flat.contains(strings.get(i))) {
13102                        return true;
13103                    }
13104                }
13105            }
13106            return false;
13107        }
13108    }
13109
13110    /**
13111     * There are three things that cmd can be:
13112     *  - a flattened component name that matches an existing activity
13113     *  - the cmd arg isn't the flattened component name of an existing activity:
13114     *    dump all activity whose component contains the cmd as a substring
13115     *  - A hex number of the ActivityRecord object instance.
13116     */
13117    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13118            int opti, boolean dumpAll) {
13119        ArrayList<ActivityRecord> activities;
13120
13121        synchronized (this) {
13122            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13123        }
13124
13125        if (activities.size() <= 0) {
13126            return false;
13127        }
13128
13129        String[] newArgs = new String[args.length - opti];
13130        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13131
13132        TaskRecord lastTask = null;
13133        boolean needSep = false;
13134        for (int i=activities.size()-1; i>=0; i--) {
13135            ActivityRecord r = activities.get(i);
13136            if (needSep) {
13137                pw.println();
13138            }
13139            needSep = true;
13140            synchronized (this) {
13141                if (lastTask != r.task) {
13142                    lastTask = r.task;
13143                    pw.print("TASK "); pw.print(lastTask.affinity);
13144                            pw.print(" id="); pw.println(lastTask.taskId);
13145                    if (dumpAll) {
13146                        lastTask.dump(pw, "  ");
13147                    }
13148                }
13149            }
13150            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13151        }
13152        return true;
13153    }
13154
13155    /**
13156     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13157     * there is a thread associated with the activity.
13158     */
13159    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13160            final ActivityRecord r, String[] args, boolean dumpAll) {
13161        String innerPrefix = prefix + "  ";
13162        synchronized (this) {
13163            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13164                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13165                    pw.print(" pid=");
13166                    if (r.app != null) pw.println(r.app.pid);
13167                    else pw.println("(not running)");
13168            if (dumpAll) {
13169                r.dump(pw, innerPrefix);
13170            }
13171        }
13172        if (r.app != null && r.app.thread != null) {
13173            // flush anything that is already in the PrintWriter since the thread is going
13174            // to write to the file descriptor directly
13175            pw.flush();
13176            try {
13177                TransferPipe tp = new TransferPipe();
13178                try {
13179                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13180                            r.appToken, innerPrefix, args);
13181                    tp.go(fd);
13182                } finally {
13183                    tp.kill();
13184                }
13185            } catch (IOException e) {
13186                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13187            } catch (RemoteException e) {
13188                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13189            }
13190        }
13191    }
13192
13193    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13194            int opti, boolean dumpAll, String dumpPackage) {
13195        boolean needSep = false;
13196        boolean onlyHistory = false;
13197        boolean printedAnything = false;
13198
13199        if ("history".equals(dumpPackage)) {
13200            if (opti < args.length && "-s".equals(args[opti])) {
13201                dumpAll = false;
13202            }
13203            onlyHistory = true;
13204            dumpPackage = null;
13205        }
13206
13207        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13208        if (!onlyHistory && dumpAll) {
13209            if (mRegisteredReceivers.size() > 0) {
13210                boolean printed = false;
13211                Iterator it = mRegisteredReceivers.values().iterator();
13212                while (it.hasNext()) {
13213                    ReceiverList r = (ReceiverList)it.next();
13214                    if (dumpPackage != null && (r.app == null ||
13215                            !dumpPackage.equals(r.app.info.packageName))) {
13216                        continue;
13217                    }
13218                    if (!printed) {
13219                        pw.println("  Registered Receivers:");
13220                        needSep = true;
13221                        printed = true;
13222                        printedAnything = true;
13223                    }
13224                    pw.print("  * "); pw.println(r);
13225                    r.dump(pw, "    ");
13226                }
13227            }
13228
13229            if (mReceiverResolver.dump(pw, needSep ?
13230                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13231                    "    ", dumpPackage, false)) {
13232                needSep = true;
13233                printedAnything = true;
13234            }
13235        }
13236
13237        for (BroadcastQueue q : mBroadcastQueues) {
13238            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13239            printedAnything |= needSep;
13240        }
13241
13242        needSep = true;
13243
13244        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13245            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13246                if (needSep) {
13247                    pw.println();
13248                }
13249                needSep = true;
13250                printedAnything = true;
13251                pw.print("  Sticky broadcasts for user ");
13252                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13253                StringBuilder sb = new StringBuilder(128);
13254                for (Map.Entry<String, ArrayList<Intent>> ent
13255                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13256                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13257                    if (dumpAll) {
13258                        pw.println(":");
13259                        ArrayList<Intent> intents = ent.getValue();
13260                        final int N = intents.size();
13261                        for (int i=0; i<N; i++) {
13262                            sb.setLength(0);
13263                            sb.append("    Intent: ");
13264                            intents.get(i).toShortString(sb, false, true, false, false);
13265                            pw.println(sb.toString());
13266                            Bundle bundle = intents.get(i).getExtras();
13267                            if (bundle != null) {
13268                                pw.print("      ");
13269                                pw.println(bundle.toString());
13270                            }
13271                        }
13272                    } else {
13273                        pw.println("");
13274                    }
13275                }
13276            }
13277        }
13278
13279        if (!onlyHistory && dumpAll) {
13280            pw.println();
13281            for (BroadcastQueue queue : mBroadcastQueues) {
13282                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13283                        + queue.mBroadcastsScheduled);
13284            }
13285            pw.println("  mHandler:");
13286            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13287            needSep = true;
13288            printedAnything = true;
13289        }
13290
13291        if (!printedAnything) {
13292            pw.println("  (nothing)");
13293        }
13294    }
13295
13296    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13297            int opti, boolean dumpAll, String dumpPackage) {
13298        boolean needSep;
13299        boolean printedAnything = false;
13300
13301        ItemMatcher matcher = new ItemMatcher();
13302        matcher.build(args, opti);
13303
13304        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13305
13306        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13307        printedAnything |= needSep;
13308
13309        if (mLaunchingProviders.size() > 0) {
13310            boolean printed = false;
13311            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13312                ContentProviderRecord r = mLaunchingProviders.get(i);
13313                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13314                    continue;
13315                }
13316                if (!printed) {
13317                    if (needSep) pw.println();
13318                    needSep = true;
13319                    pw.println("  Launching content providers:");
13320                    printed = true;
13321                    printedAnything = true;
13322                }
13323                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13324                        pw.println(r);
13325            }
13326        }
13327
13328        if (mGrantedUriPermissions.size() > 0) {
13329            boolean printed = false;
13330            int dumpUid = -2;
13331            if (dumpPackage != null) {
13332                try {
13333                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13334                } catch (NameNotFoundException e) {
13335                    dumpUid = -1;
13336                }
13337            }
13338            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13339                int uid = mGrantedUriPermissions.keyAt(i);
13340                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13341                    continue;
13342                }
13343                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13344                if (!printed) {
13345                    if (needSep) pw.println();
13346                    needSep = true;
13347                    pw.println("  Granted Uri Permissions:");
13348                    printed = true;
13349                    printedAnything = true;
13350                }
13351                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13352                for (UriPermission perm : perms.values()) {
13353                    pw.print("    "); pw.println(perm);
13354                    if (dumpAll) {
13355                        perm.dump(pw, "      ");
13356                    }
13357                }
13358            }
13359        }
13360
13361        if (!printedAnything) {
13362            pw.println("  (nothing)");
13363        }
13364    }
13365
13366    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13367            int opti, boolean dumpAll, String dumpPackage) {
13368        boolean printed = false;
13369
13370        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13371
13372        if (mIntentSenderRecords.size() > 0) {
13373            Iterator<WeakReference<PendingIntentRecord>> it
13374                    = mIntentSenderRecords.values().iterator();
13375            while (it.hasNext()) {
13376                WeakReference<PendingIntentRecord> ref = it.next();
13377                PendingIntentRecord rec = ref != null ? ref.get(): null;
13378                if (dumpPackage != null && (rec == null
13379                        || !dumpPackage.equals(rec.key.packageName))) {
13380                    continue;
13381                }
13382                printed = true;
13383                if (rec != null) {
13384                    pw.print("  * "); pw.println(rec);
13385                    if (dumpAll) {
13386                        rec.dump(pw, "    ");
13387                    }
13388                } else {
13389                    pw.print("  * "); pw.println(ref);
13390                }
13391            }
13392        }
13393
13394        if (!printed) {
13395            pw.println("  (nothing)");
13396        }
13397    }
13398
13399    private static final int dumpProcessList(PrintWriter pw,
13400            ActivityManagerService service, List list,
13401            String prefix, String normalLabel, String persistentLabel,
13402            String dumpPackage) {
13403        int numPers = 0;
13404        final int N = list.size()-1;
13405        for (int i=N; i>=0; i--) {
13406            ProcessRecord r = (ProcessRecord)list.get(i);
13407            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13408                continue;
13409            }
13410            pw.println(String.format("%s%s #%2d: %s",
13411                    prefix, (r.persistent ? persistentLabel : normalLabel),
13412                    i, r.toString()));
13413            if (r.persistent) {
13414                numPers++;
13415            }
13416        }
13417        return numPers;
13418    }
13419
13420    private static final boolean dumpProcessOomList(PrintWriter pw,
13421            ActivityManagerService service, List<ProcessRecord> origList,
13422            String prefix, String normalLabel, String persistentLabel,
13423            boolean inclDetails, String dumpPackage) {
13424
13425        ArrayList<Pair<ProcessRecord, Integer>> list
13426                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13427        for (int i=0; i<origList.size(); i++) {
13428            ProcessRecord r = origList.get(i);
13429            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13430                continue;
13431            }
13432            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13433        }
13434
13435        if (list.size() <= 0) {
13436            return false;
13437        }
13438
13439        Comparator<Pair<ProcessRecord, Integer>> comparator
13440                = new Comparator<Pair<ProcessRecord, Integer>>() {
13441            @Override
13442            public int compare(Pair<ProcessRecord, Integer> object1,
13443                    Pair<ProcessRecord, Integer> object2) {
13444                if (object1.first.setAdj != object2.first.setAdj) {
13445                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13446                }
13447                if (object1.second.intValue() != object2.second.intValue()) {
13448                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13449                }
13450                return 0;
13451            }
13452        };
13453
13454        Collections.sort(list, comparator);
13455
13456        final long curRealtime = SystemClock.elapsedRealtime();
13457        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13458        final long curUptime = SystemClock.uptimeMillis();
13459        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13460
13461        for (int i=list.size()-1; i>=0; i--) {
13462            ProcessRecord r = list.get(i).first;
13463            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13464            char schedGroup;
13465            switch (r.setSchedGroup) {
13466                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13467                    schedGroup = 'B';
13468                    break;
13469                case Process.THREAD_GROUP_DEFAULT:
13470                    schedGroup = 'F';
13471                    break;
13472                default:
13473                    schedGroup = '?';
13474                    break;
13475            }
13476            char foreground;
13477            if (r.foregroundActivities) {
13478                foreground = 'A';
13479            } else if (r.foregroundServices) {
13480                foreground = 'S';
13481            } else {
13482                foreground = ' ';
13483            }
13484            String procState = ProcessList.makeProcStateString(r.curProcState);
13485            pw.print(prefix);
13486            pw.print(r.persistent ? persistentLabel : normalLabel);
13487            pw.print(" #");
13488            int num = (origList.size()-1)-list.get(i).second;
13489            if (num < 10) pw.print(' ');
13490            pw.print(num);
13491            pw.print(": ");
13492            pw.print(oomAdj);
13493            pw.print(' ');
13494            pw.print(schedGroup);
13495            pw.print('/');
13496            pw.print(foreground);
13497            pw.print('/');
13498            pw.print(procState);
13499            pw.print(" trm:");
13500            if (r.trimMemoryLevel < 10) pw.print(' ');
13501            pw.print(r.trimMemoryLevel);
13502            pw.print(' ');
13503            pw.print(r.toShortString());
13504            pw.print(" (");
13505            pw.print(r.adjType);
13506            pw.println(')');
13507            if (r.adjSource != null || r.adjTarget != null) {
13508                pw.print(prefix);
13509                pw.print("    ");
13510                if (r.adjTarget instanceof ComponentName) {
13511                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13512                } else if (r.adjTarget != null) {
13513                    pw.print(r.adjTarget.toString());
13514                } else {
13515                    pw.print("{null}");
13516                }
13517                pw.print("<=");
13518                if (r.adjSource instanceof ProcessRecord) {
13519                    pw.print("Proc{");
13520                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13521                    pw.println("}");
13522                } else if (r.adjSource != null) {
13523                    pw.println(r.adjSource.toString());
13524                } else {
13525                    pw.println("{null}");
13526                }
13527            }
13528            if (inclDetails) {
13529                pw.print(prefix);
13530                pw.print("    ");
13531                pw.print("oom: max="); pw.print(r.maxAdj);
13532                pw.print(" curRaw="); pw.print(r.curRawAdj);
13533                pw.print(" setRaw="); pw.print(r.setRawAdj);
13534                pw.print(" cur="); pw.print(r.curAdj);
13535                pw.print(" set="); pw.println(r.setAdj);
13536                pw.print(prefix);
13537                pw.print("    ");
13538                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13539                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13540                pw.print(" lastPss="); pw.print(r.lastPss);
13541                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13542                pw.print(prefix);
13543                pw.print("    ");
13544                pw.print("cached="); pw.print(r.cached);
13545                pw.print(" empty="); pw.print(r.empty);
13546                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13547
13548                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13549                    if (r.lastWakeTime != 0) {
13550                        long wtime;
13551                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13552                        synchronized (stats) {
13553                            wtime = stats.getProcessWakeTime(r.info.uid,
13554                                    r.pid, curRealtime);
13555                        }
13556                        long timeUsed = wtime - r.lastWakeTime;
13557                        pw.print(prefix);
13558                        pw.print("    ");
13559                        pw.print("keep awake over ");
13560                        TimeUtils.formatDuration(realtimeSince, pw);
13561                        pw.print(" used ");
13562                        TimeUtils.formatDuration(timeUsed, pw);
13563                        pw.print(" (");
13564                        pw.print((timeUsed*100)/realtimeSince);
13565                        pw.println("%)");
13566                    }
13567                    if (r.lastCpuTime != 0) {
13568                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13569                        pw.print(prefix);
13570                        pw.print("    ");
13571                        pw.print("run cpu over ");
13572                        TimeUtils.formatDuration(uptimeSince, pw);
13573                        pw.print(" used ");
13574                        TimeUtils.formatDuration(timeUsed, pw);
13575                        pw.print(" (");
13576                        pw.print((timeUsed*100)/uptimeSince);
13577                        pw.println("%)");
13578                    }
13579                }
13580            }
13581        }
13582        return true;
13583    }
13584
13585    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13586            String[] args) {
13587        ArrayList<ProcessRecord> procs;
13588        synchronized (this) {
13589            if (args != null && args.length > start
13590                    && args[start].charAt(0) != '-') {
13591                procs = new ArrayList<ProcessRecord>();
13592                int pid = -1;
13593                try {
13594                    pid = Integer.parseInt(args[start]);
13595                } catch (NumberFormatException e) {
13596                }
13597                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13598                    ProcessRecord proc = mLruProcesses.get(i);
13599                    if (proc.pid == pid) {
13600                        procs.add(proc);
13601                    } else if (allPkgs && proc.pkgList != null
13602                            && proc.pkgList.containsKey(args[start])) {
13603                        procs.add(proc);
13604                    } else if (proc.processName.equals(args[start])) {
13605                        procs.add(proc);
13606                    }
13607                }
13608                if (procs.size() <= 0) {
13609                    return null;
13610                }
13611            } else {
13612                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13613            }
13614        }
13615        return procs;
13616    }
13617
13618    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13619            PrintWriter pw, String[] args) {
13620        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13621        if (procs == null) {
13622            pw.println("No process found for: " + args[0]);
13623            return;
13624        }
13625
13626        long uptime = SystemClock.uptimeMillis();
13627        long realtime = SystemClock.elapsedRealtime();
13628        pw.println("Applications Graphics Acceleration Info:");
13629        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13630
13631        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13632            ProcessRecord r = procs.get(i);
13633            if (r.thread != null) {
13634                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13635                pw.flush();
13636                try {
13637                    TransferPipe tp = new TransferPipe();
13638                    try {
13639                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13640                        tp.go(fd);
13641                    } finally {
13642                        tp.kill();
13643                    }
13644                } catch (IOException e) {
13645                    pw.println("Failure while dumping the app: " + r);
13646                    pw.flush();
13647                } catch (RemoteException e) {
13648                    pw.println("Got a RemoteException while dumping the app " + r);
13649                    pw.flush();
13650                }
13651            }
13652        }
13653    }
13654
13655    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13656        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13657        if (procs == null) {
13658            pw.println("No process found for: " + args[0]);
13659            return;
13660        }
13661
13662        pw.println("Applications Database Info:");
13663
13664        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13665            ProcessRecord r = procs.get(i);
13666            if (r.thread != null) {
13667                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13668                pw.flush();
13669                try {
13670                    TransferPipe tp = new TransferPipe();
13671                    try {
13672                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13673                        tp.go(fd);
13674                    } finally {
13675                        tp.kill();
13676                    }
13677                } catch (IOException e) {
13678                    pw.println("Failure while dumping the app: " + r);
13679                    pw.flush();
13680                } catch (RemoteException e) {
13681                    pw.println("Got a RemoteException while dumping the app " + r);
13682                    pw.flush();
13683                }
13684            }
13685        }
13686    }
13687
13688    final static class MemItem {
13689        final boolean isProc;
13690        final String label;
13691        final String shortLabel;
13692        final long pss;
13693        final int id;
13694        final boolean hasActivities;
13695        ArrayList<MemItem> subitems;
13696
13697        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13698                boolean _hasActivities) {
13699            isProc = true;
13700            label = _label;
13701            shortLabel = _shortLabel;
13702            pss = _pss;
13703            id = _id;
13704            hasActivities = _hasActivities;
13705        }
13706
13707        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13708            isProc = false;
13709            label = _label;
13710            shortLabel = _shortLabel;
13711            pss = _pss;
13712            id = _id;
13713            hasActivities = false;
13714        }
13715    }
13716
13717    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13718            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13719        if (sort && !isCompact) {
13720            Collections.sort(items, new Comparator<MemItem>() {
13721                @Override
13722                public int compare(MemItem lhs, MemItem rhs) {
13723                    if (lhs.pss < rhs.pss) {
13724                        return 1;
13725                    } else if (lhs.pss > rhs.pss) {
13726                        return -1;
13727                    }
13728                    return 0;
13729                }
13730            });
13731        }
13732
13733        for (int i=0; i<items.size(); i++) {
13734            MemItem mi = items.get(i);
13735            if (!isCompact) {
13736                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13737            } else if (mi.isProc) {
13738                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13739                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13740                pw.println(mi.hasActivities ? ",a" : ",e");
13741            } else {
13742                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13743                pw.println(mi.pss);
13744            }
13745            if (mi.subitems != null) {
13746                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13747                        true, isCompact);
13748            }
13749        }
13750    }
13751
13752    // These are in KB.
13753    static final long[] DUMP_MEM_BUCKETS = new long[] {
13754        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13755        120*1024, 160*1024, 200*1024,
13756        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13757        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13758    };
13759
13760    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13761            boolean stackLike) {
13762        int start = label.lastIndexOf('.');
13763        if (start >= 0) start++;
13764        else start = 0;
13765        int end = label.length();
13766        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13767            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13768                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13769                out.append(bucket);
13770                out.append(stackLike ? "MB." : "MB ");
13771                out.append(label, start, end);
13772                return;
13773            }
13774        }
13775        out.append(memKB/1024);
13776        out.append(stackLike ? "MB." : "MB ");
13777        out.append(label, start, end);
13778    }
13779
13780    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13781            ProcessList.NATIVE_ADJ,
13782            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13783            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13784            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13785            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13786            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13787            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13788    };
13789    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13790            "Native",
13791            "System", "Persistent", "Persistent Service", "Foreground",
13792            "Visible", "Perceptible",
13793            "Heavy Weight", "Backup",
13794            "A Services", "Home",
13795            "Previous", "B Services", "Cached"
13796    };
13797    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13798            "native",
13799            "sys", "pers", "persvc", "fore",
13800            "vis", "percept",
13801            "heavy", "backup",
13802            "servicea", "home",
13803            "prev", "serviceb", "cached"
13804    };
13805
13806    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13807            long realtime, boolean isCheckinRequest, boolean isCompact) {
13808        if (isCheckinRequest || isCompact) {
13809            // short checkin version
13810            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13811        } else {
13812            pw.println("Applications Memory Usage (kB):");
13813            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13814        }
13815    }
13816
13817    private static final int KSM_SHARED = 0;
13818    private static final int KSM_SHARING = 1;
13819    private static final int KSM_UNSHARED = 2;
13820    private static final int KSM_VOLATILE = 3;
13821
13822    private final long[] getKsmInfo() {
13823        long[] longOut = new long[4];
13824        final int[] SINGLE_LONG_FORMAT = new int[] {
13825            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13826        };
13827        long[] longTmp = new long[1];
13828        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13829                SINGLE_LONG_FORMAT, null, longTmp, null);
13830        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13831        longTmp[0] = 0;
13832        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13833                SINGLE_LONG_FORMAT, null, longTmp, null);
13834        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13835        longTmp[0] = 0;
13836        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13837                SINGLE_LONG_FORMAT, null, longTmp, null);
13838        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13839        longTmp[0] = 0;
13840        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13841                SINGLE_LONG_FORMAT, null, longTmp, null);
13842        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13843        return longOut;
13844    }
13845
13846    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13847            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13848        boolean dumpDetails = false;
13849        boolean dumpFullDetails = false;
13850        boolean dumpDalvik = false;
13851        boolean oomOnly = false;
13852        boolean isCompact = false;
13853        boolean localOnly = false;
13854        boolean packages = false;
13855
13856        int opti = 0;
13857        while (opti < args.length) {
13858            String opt = args[opti];
13859            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13860                break;
13861            }
13862            opti++;
13863            if ("-a".equals(opt)) {
13864                dumpDetails = true;
13865                dumpFullDetails = true;
13866                dumpDalvik = true;
13867            } else if ("-d".equals(opt)) {
13868                dumpDalvik = true;
13869            } else if ("-c".equals(opt)) {
13870                isCompact = true;
13871            } else if ("--oom".equals(opt)) {
13872                oomOnly = true;
13873            } else if ("--local".equals(opt)) {
13874                localOnly = true;
13875            } else if ("--package".equals(opt)) {
13876                packages = true;
13877            } else if ("-h".equals(opt)) {
13878                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13879                pw.println("  -a: include all available information for each process.");
13880                pw.println("  -d: include dalvik details when dumping process details.");
13881                pw.println("  -c: dump in a compact machine-parseable representation.");
13882                pw.println("  --oom: only show processes organized by oom adj.");
13883                pw.println("  --local: only collect details locally, don't call process.");
13884                pw.println("  --package: interpret process arg as package, dumping all");
13885                pw.println("             processes that have loaded that package.");
13886                pw.println("If [process] is specified it can be the name or ");
13887                pw.println("pid of a specific process to dump.");
13888                return;
13889            } else {
13890                pw.println("Unknown argument: " + opt + "; use -h for help");
13891            }
13892        }
13893
13894        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13895        long uptime = SystemClock.uptimeMillis();
13896        long realtime = SystemClock.elapsedRealtime();
13897        final long[] tmpLong = new long[1];
13898
13899        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13900        if (procs == null) {
13901            // No Java processes.  Maybe they want to print a native process.
13902            if (args != null && args.length > opti
13903                    && args[opti].charAt(0) != '-') {
13904                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13905                        = new ArrayList<ProcessCpuTracker.Stats>();
13906                updateCpuStatsNow();
13907                int findPid = -1;
13908                try {
13909                    findPid = Integer.parseInt(args[opti]);
13910                } catch (NumberFormatException e) {
13911                }
13912                synchronized (mProcessCpuTracker) {
13913                    final int N = mProcessCpuTracker.countStats();
13914                    for (int i=0; i<N; i++) {
13915                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13916                        if (st.pid == findPid || (st.baseName != null
13917                                && st.baseName.equals(args[opti]))) {
13918                            nativeProcs.add(st);
13919                        }
13920                    }
13921                }
13922                if (nativeProcs.size() > 0) {
13923                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13924                            isCompact);
13925                    Debug.MemoryInfo mi = null;
13926                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13927                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13928                        final int pid = r.pid;
13929                        if (!isCheckinRequest && dumpDetails) {
13930                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13931                        }
13932                        if (mi == null) {
13933                            mi = new Debug.MemoryInfo();
13934                        }
13935                        if (dumpDetails || (!brief && !oomOnly)) {
13936                            Debug.getMemoryInfo(pid, mi);
13937                        } else {
13938                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13939                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13940                        }
13941                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13942                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13943                        if (isCheckinRequest) {
13944                            pw.println();
13945                        }
13946                    }
13947                    return;
13948                }
13949            }
13950            pw.println("No process found for: " + args[opti]);
13951            return;
13952        }
13953
13954        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13955            dumpDetails = true;
13956        }
13957
13958        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13959
13960        String[] innerArgs = new String[args.length-opti];
13961        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13962
13963        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13964        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13965        long nativePss=0, dalvikPss=0, otherPss=0;
13966        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13967
13968        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13969        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13970                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13971
13972        long totalPss = 0;
13973        long cachedPss = 0;
13974
13975        Debug.MemoryInfo mi = null;
13976        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13977            final ProcessRecord r = procs.get(i);
13978            final IApplicationThread thread;
13979            final int pid;
13980            final int oomAdj;
13981            final boolean hasActivities;
13982            synchronized (this) {
13983                thread = r.thread;
13984                pid = r.pid;
13985                oomAdj = r.getSetAdjWithServices();
13986                hasActivities = r.activities.size() > 0;
13987            }
13988            if (thread != null) {
13989                if (!isCheckinRequest && dumpDetails) {
13990                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13991                }
13992                if (mi == null) {
13993                    mi = new Debug.MemoryInfo();
13994                }
13995                if (dumpDetails || (!brief && !oomOnly)) {
13996                    Debug.getMemoryInfo(pid, mi);
13997                } else {
13998                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13999                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14000                }
14001                if (dumpDetails) {
14002                    if (localOnly) {
14003                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14004                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14005                        if (isCheckinRequest) {
14006                            pw.println();
14007                        }
14008                    } else {
14009                        try {
14010                            pw.flush();
14011                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14012                                    dumpDalvik, innerArgs);
14013                        } catch (RemoteException e) {
14014                            if (!isCheckinRequest) {
14015                                pw.println("Got RemoteException!");
14016                                pw.flush();
14017                            }
14018                        }
14019                    }
14020                }
14021
14022                final long myTotalPss = mi.getTotalPss();
14023                final long myTotalUss = mi.getTotalUss();
14024
14025                synchronized (this) {
14026                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14027                        // Record this for posterity if the process has been stable.
14028                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14029                    }
14030                }
14031
14032                if (!isCheckinRequest && mi != null) {
14033                    totalPss += myTotalPss;
14034                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14035                            (hasActivities ? " / activities)" : ")"),
14036                            r.processName, myTotalPss, pid, hasActivities);
14037                    procMems.add(pssItem);
14038                    procMemsMap.put(pid, pssItem);
14039
14040                    nativePss += mi.nativePss;
14041                    dalvikPss += mi.dalvikPss;
14042                    otherPss += mi.otherPss;
14043                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14044                        long mem = mi.getOtherPss(j);
14045                        miscPss[j] += mem;
14046                        otherPss -= mem;
14047                    }
14048
14049                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14050                        cachedPss += myTotalPss;
14051                    }
14052
14053                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14054                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14055                                || oomIndex == (oomPss.length-1)) {
14056                            oomPss[oomIndex] += myTotalPss;
14057                            if (oomProcs[oomIndex] == null) {
14058                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14059                            }
14060                            oomProcs[oomIndex].add(pssItem);
14061                            break;
14062                        }
14063                    }
14064                }
14065            }
14066        }
14067
14068        long nativeProcTotalPss = 0;
14069
14070        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14071            // If we are showing aggregations, also look for native processes to
14072            // include so that our aggregations are more accurate.
14073            updateCpuStatsNow();
14074            synchronized (mProcessCpuTracker) {
14075                final int N = mProcessCpuTracker.countStats();
14076                for (int i=0; i<N; i++) {
14077                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14078                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14079                        if (mi == null) {
14080                            mi = new Debug.MemoryInfo();
14081                        }
14082                        if (!brief && !oomOnly) {
14083                            Debug.getMemoryInfo(st.pid, mi);
14084                        } else {
14085                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14086                            mi.nativePrivateDirty = (int)tmpLong[0];
14087                        }
14088
14089                        final long myTotalPss = mi.getTotalPss();
14090                        totalPss += myTotalPss;
14091                        nativeProcTotalPss += myTotalPss;
14092
14093                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14094                                st.name, myTotalPss, st.pid, false);
14095                        procMems.add(pssItem);
14096
14097                        nativePss += mi.nativePss;
14098                        dalvikPss += mi.dalvikPss;
14099                        otherPss += mi.otherPss;
14100                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14101                            long mem = mi.getOtherPss(j);
14102                            miscPss[j] += mem;
14103                            otherPss -= mem;
14104                        }
14105                        oomPss[0] += myTotalPss;
14106                        if (oomProcs[0] == null) {
14107                            oomProcs[0] = new ArrayList<MemItem>();
14108                        }
14109                        oomProcs[0].add(pssItem);
14110                    }
14111                }
14112            }
14113
14114            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14115
14116            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14117            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14118            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14119            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14120                String label = Debug.MemoryInfo.getOtherLabel(j);
14121                catMems.add(new MemItem(label, label, miscPss[j], j));
14122            }
14123
14124            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14125            for (int j=0; j<oomPss.length; j++) {
14126                if (oomPss[j] != 0) {
14127                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14128                            : DUMP_MEM_OOM_LABEL[j];
14129                    MemItem item = new MemItem(label, label, oomPss[j],
14130                            DUMP_MEM_OOM_ADJ[j]);
14131                    item.subitems = oomProcs[j];
14132                    oomMems.add(item);
14133                }
14134            }
14135
14136            if (!brief && !oomOnly && !isCompact) {
14137                pw.println();
14138                pw.println("Total PSS by process:");
14139                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14140                pw.println();
14141            }
14142            if (!isCompact) {
14143                pw.println("Total PSS by OOM adjustment:");
14144            }
14145            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14146            if (!brief && !oomOnly) {
14147                PrintWriter out = categoryPw != null ? categoryPw : pw;
14148                if (!isCompact) {
14149                    out.println();
14150                    out.println("Total PSS by category:");
14151                }
14152                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14153            }
14154            if (!isCompact) {
14155                pw.println();
14156            }
14157            MemInfoReader memInfo = new MemInfoReader();
14158            memInfo.readMemInfo();
14159            if (nativeProcTotalPss > 0) {
14160                synchronized (this) {
14161                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14162                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14163                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14164                }
14165            }
14166            if (!brief) {
14167                if (!isCompact) {
14168                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14169                    pw.print(" kB (status ");
14170                    switch (mLastMemoryLevel) {
14171                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14172                            pw.println("normal)");
14173                            break;
14174                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14175                            pw.println("moderate)");
14176                            break;
14177                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14178                            pw.println("low)");
14179                            break;
14180                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14181                            pw.println("critical)");
14182                            break;
14183                        default:
14184                            pw.print(mLastMemoryLevel);
14185                            pw.println(")");
14186                            break;
14187                    }
14188                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14189                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14190                            pw.print(cachedPss); pw.print(" cached pss + ");
14191                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14192                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14193                } else {
14194                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14195                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14196                            + memInfo.getFreeSizeKb()); pw.print(",");
14197                    pw.println(totalPss - cachedPss);
14198                }
14199            }
14200            if (!isCompact) {
14201                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14202                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14203                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14204                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14205                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14206                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14207                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14208            }
14209            if (!brief) {
14210                if (memInfo.getZramTotalSizeKb() != 0) {
14211                    if (!isCompact) {
14212                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14213                                pw.print(" kB physical used for ");
14214                                pw.print(memInfo.getSwapTotalSizeKb()
14215                                        - memInfo.getSwapFreeSizeKb());
14216                                pw.print(" kB in swap (");
14217                                pw.print(memInfo.getSwapTotalSizeKb());
14218                                pw.println(" kB total swap)");
14219                    } else {
14220                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14221                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14222                                pw.println(memInfo.getSwapFreeSizeKb());
14223                    }
14224                }
14225                final long[] ksm = getKsmInfo();
14226                if (!isCompact) {
14227                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14228                            || ksm[KSM_VOLATILE] != 0) {
14229                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14230                                pw.print(" kB saved from shared ");
14231                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14232                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14233                                pw.print(" kB unshared; ");
14234                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14235                    }
14236                    pw.print("   Tuning: ");
14237                    pw.print(ActivityManager.staticGetMemoryClass());
14238                    pw.print(" (large ");
14239                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14240                    pw.print("), oom ");
14241                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14242                    pw.print(" kB");
14243                    pw.print(", restore limit ");
14244                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14245                    pw.print(" kB");
14246                    if (ActivityManager.isLowRamDeviceStatic()) {
14247                        pw.print(" (low-ram)");
14248                    }
14249                    if (ActivityManager.isHighEndGfx()) {
14250                        pw.print(" (high-end-gfx)");
14251                    }
14252                    pw.println();
14253                } else {
14254                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14255                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14256                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14257                    pw.print("tuning,");
14258                    pw.print(ActivityManager.staticGetMemoryClass());
14259                    pw.print(',');
14260                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14261                    pw.print(',');
14262                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14263                    if (ActivityManager.isLowRamDeviceStatic()) {
14264                        pw.print(",low-ram");
14265                    }
14266                    if (ActivityManager.isHighEndGfx()) {
14267                        pw.print(",high-end-gfx");
14268                    }
14269                    pw.println();
14270                }
14271            }
14272        }
14273    }
14274
14275    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14276            String name) {
14277        sb.append("  ");
14278        sb.append(ProcessList.makeOomAdjString(oomAdj));
14279        sb.append(' ');
14280        sb.append(ProcessList.makeProcStateString(procState));
14281        sb.append(' ');
14282        ProcessList.appendRamKb(sb, pss);
14283        sb.append(" kB: ");
14284        sb.append(name);
14285    }
14286
14287    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14288        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14289        sb.append(" (");
14290        sb.append(mi.pid);
14291        sb.append(") ");
14292        sb.append(mi.adjType);
14293        sb.append('\n');
14294        if (mi.adjReason != null) {
14295            sb.append("                      ");
14296            sb.append(mi.adjReason);
14297            sb.append('\n');
14298        }
14299    }
14300
14301    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14302        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14303        for (int i=0, N=memInfos.size(); i<N; i++) {
14304            ProcessMemInfo mi = memInfos.get(i);
14305            infoMap.put(mi.pid, mi);
14306        }
14307        updateCpuStatsNow();
14308        synchronized (mProcessCpuTracker) {
14309            final int N = mProcessCpuTracker.countStats();
14310            for (int i=0; i<N; i++) {
14311                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14312                if (st.vsize > 0) {
14313                    long pss = Debug.getPss(st.pid, null);
14314                    if (pss > 0) {
14315                        if (infoMap.indexOfKey(st.pid) < 0) {
14316                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14317                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14318                            mi.pss = pss;
14319                            memInfos.add(mi);
14320                        }
14321                    }
14322                }
14323            }
14324        }
14325
14326        long totalPss = 0;
14327        for (int i=0, N=memInfos.size(); i<N; i++) {
14328            ProcessMemInfo mi = memInfos.get(i);
14329            if (mi.pss == 0) {
14330                mi.pss = Debug.getPss(mi.pid, null);
14331            }
14332            totalPss += mi.pss;
14333        }
14334        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14335            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14336                if (lhs.oomAdj != rhs.oomAdj) {
14337                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14338                }
14339                if (lhs.pss != rhs.pss) {
14340                    return lhs.pss < rhs.pss ? 1 : -1;
14341                }
14342                return 0;
14343            }
14344        });
14345
14346        StringBuilder tag = new StringBuilder(128);
14347        StringBuilder stack = new StringBuilder(128);
14348        tag.append("Low on memory -- ");
14349        appendMemBucket(tag, totalPss, "total", false);
14350        appendMemBucket(stack, totalPss, "total", true);
14351
14352        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14353        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14354        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14355
14356        boolean firstLine = true;
14357        int lastOomAdj = Integer.MIN_VALUE;
14358        long extraNativeRam = 0;
14359        long cachedPss = 0;
14360        for (int i=0, N=memInfos.size(); i<N; i++) {
14361            ProcessMemInfo mi = memInfos.get(i);
14362
14363            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14364                cachedPss += mi.pss;
14365            }
14366
14367            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14368                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14369                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14370                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14371                if (lastOomAdj != mi.oomAdj) {
14372                    lastOomAdj = mi.oomAdj;
14373                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14374                        tag.append(" / ");
14375                    }
14376                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14377                        if (firstLine) {
14378                            stack.append(":");
14379                            firstLine = false;
14380                        }
14381                        stack.append("\n\t at ");
14382                    } else {
14383                        stack.append("$");
14384                    }
14385                } else {
14386                    tag.append(" ");
14387                    stack.append("$");
14388                }
14389                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14390                    appendMemBucket(tag, mi.pss, mi.name, false);
14391                }
14392                appendMemBucket(stack, mi.pss, mi.name, true);
14393                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14394                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14395                    stack.append("(");
14396                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14397                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14398                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14399                            stack.append(":");
14400                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14401                        }
14402                    }
14403                    stack.append(")");
14404                }
14405            }
14406
14407            appendMemInfo(fullNativeBuilder, mi);
14408            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14409                // The short form only has native processes that are >= 1MB.
14410                if (mi.pss >= 1000) {
14411                    appendMemInfo(shortNativeBuilder, mi);
14412                } else {
14413                    extraNativeRam += mi.pss;
14414                }
14415            } else {
14416                // Short form has all other details, but if we have collected RAM
14417                // from smaller native processes let's dump a summary of that.
14418                if (extraNativeRam > 0) {
14419                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14420                            -1, extraNativeRam, "(Other native)");
14421                    shortNativeBuilder.append('\n');
14422                    extraNativeRam = 0;
14423                }
14424                appendMemInfo(fullJavaBuilder, mi);
14425            }
14426        }
14427
14428        fullJavaBuilder.append("           ");
14429        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14430        fullJavaBuilder.append(" kB: TOTAL\n");
14431
14432        MemInfoReader memInfo = new MemInfoReader();
14433        memInfo.readMemInfo();
14434        final long[] infos = memInfo.getRawInfo();
14435
14436        StringBuilder memInfoBuilder = new StringBuilder(1024);
14437        Debug.getMemInfo(infos);
14438        memInfoBuilder.append("  MemInfo: ");
14439        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14440        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14441        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14442        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14443        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14444        memInfoBuilder.append("           ");
14445        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14446        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14447        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14448        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14449        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14450            memInfoBuilder.append("  ZRAM: ");
14451            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14452            memInfoBuilder.append(" kB RAM, ");
14453            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14454            memInfoBuilder.append(" kB swap total, ");
14455            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14456            memInfoBuilder.append(" kB swap free\n");
14457        }
14458        final long[] ksm = getKsmInfo();
14459        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14460                || ksm[KSM_VOLATILE] != 0) {
14461            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14462            memInfoBuilder.append(" kB saved from shared ");
14463            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14464            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14465            memInfoBuilder.append(" kB unshared; ");
14466            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14467        }
14468        memInfoBuilder.append("  Free RAM: ");
14469        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14470                + memInfo.getFreeSizeKb());
14471        memInfoBuilder.append(" kB\n");
14472        memInfoBuilder.append("  Used RAM: ");
14473        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14474        memInfoBuilder.append(" kB\n");
14475        memInfoBuilder.append("  Lost RAM: ");
14476        memInfoBuilder.append(memInfo.getTotalSizeKb()
14477                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14478                - memInfo.getKernelUsedSizeKb());
14479        memInfoBuilder.append(" kB\n");
14480        Slog.i(TAG, "Low on memory:");
14481        Slog.i(TAG, shortNativeBuilder.toString());
14482        Slog.i(TAG, fullJavaBuilder.toString());
14483        Slog.i(TAG, memInfoBuilder.toString());
14484
14485        StringBuilder dropBuilder = new StringBuilder(1024);
14486        /*
14487        StringWriter oomSw = new StringWriter();
14488        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14489        StringWriter catSw = new StringWriter();
14490        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14491        String[] emptyArgs = new String[] { };
14492        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14493        oomPw.flush();
14494        String oomString = oomSw.toString();
14495        */
14496        dropBuilder.append("Low on memory:");
14497        dropBuilder.append(stack);
14498        dropBuilder.append('\n');
14499        dropBuilder.append(fullNativeBuilder);
14500        dropBuilder.append(fullJavaBuilder);
14501        dropBuilder.append('\n');
14502        dropBuilder.append(memInfoBuilder);
14503        dropBuilder.append('\n');
14504        /*
14505        dropBuilder.append(oomString);
14506        dropBuilder.append('\n');
14507        */
14508        StringWriter catSw = new StringWriter();
14509        synchronized (ActivityManagerService.this) {
14510            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14511            String[] emptyArgs = new String[] { };
14512            catPw.println();
14513            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14514            catPw.println();
14515            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14516                    false, false, null);
14517            catPw.println();
14518            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14519            catPw.flush();
14520        }
14521        dropBuilder.append(catSw.toString());
14522        addErrorToDropBox("lowmem", null, "system_server", null,
14523                null, tag.toString(), dropBuilder.toString(), null, null);
14524        //Slog.i(TAG, "Sent to dropbox:");
14525        //Slog.i(TAG, dropBuilder.toString());
14526        synchronized (ActivityManagerService.this) {
14527            long now = SystemClock.uptimeMillis();
14528            if (mLastMemUsageReportTime < now) {
14529                mLastMemUsageReportTime = now;
14530            }
14531        }
14532    }
14533
14534    /**
14535     * Searches array of arguments for the specified string
14536     * @param args array of argument strings
14537     * @param value value to search for
14538     * @return true if the value is contained in the array
14539     */
14540    private static boolean scanArgs(String[] args, String value) {
14541        if (args != null) {
14542            for (String arg : args) {
14543                if (value.equals(arg)) {
14544                    return true;
14545                }
14546            }
14547        }
14548        return false;
14549    }
14550
14551    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14552            ContentProviderRecord cpr, boolean always) {
14553        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14554
14555        if (!inLaunching || always) {
14556            synchronized (cpr) {
14557                cpr.launchingApp = null;
14558                cpr.notifyAll();
14559            }
14560            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14561            String names[] = cpr.info.authority.split(";");
14562            for (int j = 0; j < names.length; j++) {
14563                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14564            }
14565        }
14566
14567        for (int i=0; i<cpr.connections.size(); i++) {
14568            ContentProviderConnection conn = cpr.connections.get(i);
14569            if (conn.waiting) {
14570                // If this connection is waiting for the provider, then we don't
14571                // need to mess with its process unless we are always removing
14572                // or for some reason the provider is not currently launching.
14573                if (inLaunching && !always) {
14574                    continue;
14575                }
14576            }
14577            ProcessRecord capp = conn.client;
14578            conn.dead = true;
14579            if (conn.stableCount > 0) {
14580                if (!capp.persistent && capp.thread != null
14581                        && capp.pid != 0
14582                        && capp.pid != MY_PID) {
14583                    capp.kill("depends on provider "
14584                            + cpr.name.flattenToShortString()
14585                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14586                }
14587            } else if (capp.thread != null && conn.provider.provider != null) {
14588                try {
14589                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14590                } catch (RemoteException e) {
14591                }
14592                // In the protocol here, we don't expect the client to correctly
14593                // clean up this connection, we'll just remove it.
14594                cpr.connections.remove(i);
14595                conn.client.conProviders.remove(conn);
14596            }
14597        }
14598
14599        if (inLaunching && always) {
14600            mLaunchingProviders.remove(cpr);
14601        }
14602        return inLaunching;
14603    }
14604
14605    /**
14606     * Main code for cleaning up a process when it has gone away.  This is
14607     * called both as a result of the process dying, or directly when stopping
14608     * a process when running in single process mode.
14609     *
14610     * @return Returns true if the given process has been restarted, so the
14611     * app that was passed in must remain on the process lists.
14612     */
14613    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14614            boolean restarting, boolean allowRestart, int index) {
14615        if (index >= 0) {
14616            removeLruProcessLocked(app);
14617            ProcessList.remove(app.pid);
14618        }
14619
14620        mProcessesToGc.remove(app);
14621        mPendingPssProcesses.remove(app);
14622
14623        // Dismiss any open dialogs.
14624        if (app.crashDialog != null && !app.forceCrashReport) {
14625            app.crashDialog.dismiss();
14626            app.crashDialog = null;
14627        }
14628        if (app.anrDialog != null) {
14629            app.anrDialog.dismiss();
14630            app.anrDialog = null;
14631        }
14632        if (app.waitDialog != null) {
14633            app.waitDialog.dismiss();
14634            app.waitDialog = null;
14635        }
14636
14637        app.crashing = false;
14638        app.notResponding = false;
14639
14640        app.resetPackageList(mProcessStats);
14641        app.unlinkDeathRecipient();
14642        app.makeInactive(mProcessStats);
14643        app.waitingToKill = null;
14644        app.forcingToForeground = null;
14645        updateProcessForegroundLocked(app, false, false);
14646        app.foregroundActivities = false;
14647        app.hasShownUi = false;
14648        app.treatLikeActivity = false;
14649        app.hasAboveClient = false;
14650        app.hasClientActivities = false;
14651
14652        mServices.killServicesLocked(app, allowRestart);
14653
14654        boolean restart = false;
14655
14656        // Remove published content providers.
14657        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14658            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14659            final boolean always = app.bad || !allowRestart;
14660            if (removeDyingProviderLocked(app, cpr, always) || always) {
14661                // We left the provider in the launching list, need to
14662                // restart it.
14663                restart = true;
14664            }
14665
14666            cpr.provider = null;
14667            cpr.proc = null;
14668        }
14669        app.pubProviders.clear();
14670
14671        // Take care of any launching providers waiting for this process.
14672        if (checkAppInLaunchingProvidersLocked(app, false)) {
14673            restart = true;
14674        }
14675
14676        // Unregister from connected content providers.
14677        if (!app.conProviders.isEmpty()) {
14678            for (int i=0; i<app.conProviders.size(); i++) {
14679                ContentProviderConnection conn = app.conProviders.get(i);
14680                conn.provider.connections.remove(conn);
14681            }
14682            app.conProviders.clear();
14683        }
14684
14685        // At this point there may be remaining entries in mLaunchingProviders
14686        // where we were the only one waiting, so they are no longer of use.
14687        // Look for these and clean up if found.
14688        // XXX Commented out for now.  Trying to figure out a way to reproduce
14689        // the actual situation to identify what is actually going on.
14690        if (false) {
14691            for (int i=0; i<mLaunchingProviders.size(); i++) {
14692                ContentProviderRecord cpr = (ContentProviderRecord)
14693                        mLaunchingProviders.get(i);
14694                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14695                    synchronized (cpr) {
14696                        cpr.launchingApp = null;
14697                        cpr.notifyAll();
14698                    }
14699                }
14700            }
14701        }
14702
14703        skipCurrentReceiverLocked(app);
14704
14705        // Unregister any receivers.
14706        for (int i=app.receivers.size()-1; i>=0; i--) {
14707            removeReceiverLocked(app.receivers.valueAt(i));
14708        }
14709        app.receivers.clear();
14710
14711        // If the app is undergoing backup, tell the backup manager about it
14712        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14713            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14714                    + mBackupTarget.appInfo + " died during backup");
14715            try {
14716                IBackupManager bm = IBackupManager.Stub.asInterface(
14717                        ServiceManager.getService(Context.BACKUP_SERVICE));
14718                bm.agentDisconnected(app.info.packageName);
14719            } catch (RemoteException e) {
14720                // can't happen; backup manager is local
14721            }
14722        }
14723
14724        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14725            ProcessChangeItem item = mPendingProcessChanges.get(i);
14726            if (item.pid == app.pid) {
14727                mPendingProcessChanges.remove(i);
14728                mAvailProcessChanges.add(item);
14729            }
14730        }
14731        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14732
14733        // If the caller is restarting this app, then leave it in its
14734        // current lists and let the caller take care of it.
14735        if (restarting) {
14736            return false;
14737        }
14738
14739        if (!app.persistent || app.isolated) {
14740            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14741                    "Removing non-persistent process during cleanup: " + app);
14742            mProcessNames.remove(app.processName, app.uid);
14743            mIsolatedProcesses.remove(app.uid);
14744            if (mHeavyWeightProcess == app) {
14745                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14746                        mHeavyWeightProcess.userId, 0));
14747                mHeavyWeightProcess = null;
14748            }
14749        } else if (!app.removed) {
14750            // This app is persistent, so we need to keep its record around.
14751            // If it is not already on the pending app list, add it there
14752            // and start a new process for it.
14753            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14754                mPersistentStartingProcesses.add(app);
14755                restart = true;
14756            }
14757        }
14758        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14759                "Clean-up removing on hold: " + app);
14760        mProcessesOnHold.remove(app);
14761
14762        if (app == mHomeProcess) {
14763            mHomeProcess = null;
14764        }
14765        if (app == mPreviousProcess) {
14766            mPreviousProcess = null;
14767        }
14768
14769        if (restart && !app.isolated) {
14770            // We have components that still need to be running in the
14771            // process, so re-launch it.
14772            if (index < 0) {
14773                ProcessList.remove(app.pid);
14774            }
14775            mProcessNames.put(app.processName, app.uid, app);
14776            startProcessLocked(app, "restart", app.processName);
14777            return true;
14778        } else if (app.pid > 0 && app.pid != MY_PID) {
14779            // Goodbye!
14780            boolean removed;
14781            synchronized (mPidsSelfLocked) {
14782                mPidsSelfLocked.remove(app.pid);
14783                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14784            }
14785            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14786            if (app.isolated) {
14787                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14788            }
14789            app.setPid(0);
14790        }
14791        return false;
14792    }
14793
14794    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14795        // Look through the content providers we are waiting to have launched,
14796        // and if any run in this process then either schedule a restart of
14797        // the process or kill the client waiting for it if this process has
14798        // gone bad.
14799        int NL = mLaunchingProviders.size();
14800        boolean restart = false;
14801        for (int i=0; i<NL; i++) {
14802            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14803            if (cpr.launchingApp == app) {
14804                if (!alwaysBad && !app.bad) {
14805                    restart = true;
14806                } else {
14807                    removeDyingProviderLocked(app, cpr, true);
14808                    // cpr should have been removed from mLaunchingProviders
14809                    NL = mLaunchingProviders.size();
14810                    i--;
14811                }
14812            }
14813        }
14814        return restart;
14815    }
14816
14817    // =========================================================
14818    // SERVICES
14819    // =========================================================
14820
14821    @Override
14822    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14823            int flags) {
14824        enforceNotIsolatedCaller("getServices");
14825        synchronized (this) {
14826            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14827        }
14828    }
14829
14830    @Override
14831    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14832        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14833        synchronized (this) {
14834            return mServices.getRunningServiceControlPanelLocked(name);
14835        }
14836    }
14837
14838    @Override
14839    public ComponentName startService(IApplicationThread caller, Intent service,
14840            String resolvedType, int userId) {
14841        enforceNotIsolatedCaller("startService");
14842        // Refuse possible leaked file descriptors
14843        if (service != null && service.hasFileDescriptors() == true) {
14844            throw new IllegalArgumentException("File descriptors passed in Intent");
14845        }
14846
14847        if (DEBUG_SERVICE)
14848            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14849        synchronized(this) {
14850            final int callingPid = Binder.getCallingPid();
14851            final int callingUid = Binder.getCallingUid();
14852            final long origId = Binder.clearCallingIdentity();
14853            ComponentName res = mServices.startServiceLocked(caller, service,
14854                    resolvedType, callingPid, callingUid, userId);
14855            Binder.restoreCallingIdentity(origId);
14856            return res;
14857        }
14858    }
14859
14860    ComponentName startServiceInPackage(int uid,
14861            Intent service, String resolvedType, int userId) {
14862        synchronized(this) {
14863            if (DEBUG_SERVICE)
14864                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14865            final long origId = Binder.clearCallingIdentity();
14866            ComponentName res = mServices.startServiceLocked(null, service,
14867                    resolvedType, -1, uid, userId);
14868            Binder.restoreCallingIdentity(origId);
14869            return res;
14870        }
14871    }
14872
14873    @Override
14874    public int stopService(IApplicationThread caller, Intent service,
14875            String resolvedType, int userId) {
14876        enforceNotIsolatedCaller("stopService");
14877        // Refuse possible leaked file descriptors
14878        if (service != null && service.hasFileDescriptors() == true) {
14879            throw new IllegalArgumentException("File descriptors passed in Intent");
14880        }
14881
14882        synchronized(this) {
14883            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14884        }
14885    }
14886
14887    @Override
14888    public IBinder peekService(Intent service, String resolvedType) {
14889        enforceNotIsolatedCaller("peekService");
14890        // Refuse possible leaked file descriptors
14891        if (service != null && service.hasFileDescriptors() == true) {
14892            throw new IllegalArgumentException("File descriptors passed in Intent");
14893        }
14894        synchronized(this) {
14895            return mServices.peekServiceLocked(service, resolvedType);
14896        }
14897    }
14898
14899    @Override
14900    public boolean stopServiceToken(ComponentName className, IBinder token,
14901            int startId) {
14902        synchronized(this) {
14903            return mServices.stopServiceTokenLocked(className, token, startId);
14904        }
14905    }
14906
14907    @Override
14908    public void setServiceForeground(ComponentName className, IBinder token,
14909            int id, Notification notification, boolean removeNotification) {
14910        synchronized(this) {
14911            mServices.setServiceForegroundLocked(className, token, id, notification,
14912                    removeNotification);
14913        }
14914    }
14915
14916    @Override
14917    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14918            boolean requireFull, String name, String callerPackage) {
14919        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14920                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14921    }
14922
14923    int unsafeConvertIncomingUser(int userId) {
14924        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14925                ? mCurrentUserId : userId;
14926    }
14927
14928    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14929            int allowMode, String name, String callerPackage) {
14930        final int callingUserId = UserHandle.getUserId(callingUid);
14931        if (callingUserId == userId) {
14932            return userId;
14933        }
14934
14935        // Note that we may be accessing mCurrentUserId outside of a lock...
14936        // shouldn't be a big deal, if this is being called outside
14937        // of a locked context there is intrinsically a race with
14938        // the value the caller will receive and someone else changing it.
14939        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14940        // we will switch to the calling user if access to the current user fails.
14941        int targetUserId = unsafeConvertIncomingUser(userId);
14942
14943        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14944            final boolean allow;
14945            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14946                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14947                // If the caller has this permission, they always pass go.  And collect $200.
14948                allow = true;
14949            } else if (allowMode == ALLOW_FULL_ONLY) {
14950                // We require full access, sucks to be you.
14951                allow = false;
14952            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14953                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14954                // If the caller does not have either permission, they are always doomed.
14955                allow = false;
14956            } else if (allowMode == ALLOW_NON_FULL) {
14957                // We are blanket allowing non-full access, you lucky caller!
14958                allow = true;
14959            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14960                // We may or may not allow this depending on whether the two users are
14961                // in the same profile.
14962                synchronized (mUserProfileGroupIdsSelfLocked) {
14963                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14964                            UserInfo.NO_PROFILE_GROUP_ID);
14965                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14966                            UserInfo.NO_PROFILE_GROUP_ID);
14967                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14968                            && callingProfile == targetProfile;
14969                }
14970            } else {
14971                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14972            }
14973            if (!allow) {
14974                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14975                    // In this case, they would like to just execute as their
14976                    // owner user instead of failing.
14977                    targetUserId = callingUserId;
14978                } else {
14979                    StringBuilder builder = new StringBuilder(128);
14980                    builder.append("Permission Denial: ");
14981                    builder.append(name);
14982                    if (callerPackage != null) {
14983                        builder.append(" from ");
14984                        builder.append(callerPackage);
14985                    }
14986                    builder.append(" asks to run as user ");
14987                    builder.append(userId);
14988                    builder.append(" but is calling from user ");
14989                    builder.append(UserHandle.getUserId(callingUid));
14990                    builder.append("; this requires ");
14991                    builder.append(INTERACT_ACROSS_USERS_FULL);
14992                    if (allowMode != ALLOW_FULL_ONLY) {
14993                        builder.append(" or ");
14994                        builder.append(INTERACT_ACROSS_USERS);
14995                    }
14996                    String msg = builder.toString();
14997                    Slog.w(TAG, msg);
14998                    throw new SecurityException(msg);
14999                }
15000            }
15001        }
15002        if (!allowAll && targetUserId < 0) {
15003            throw new IllegalArgumentException(
15004                    "Call does not support special user #" + targetUserId);
15005        }
15006        // Check shell permission
15007        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15008            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15009                    targetUserId)) {
15010                throw new SecurityException("Shell does not have permission to access user "
15011                        + targetUserId + "\n " + Debug.getCallers(3));
15012            }
15013        }
15014        return targetUserId;
15015    }
15016
15017    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15018            String className, int flags) {
15019        boolean result = false;
15020        // For apps that don't have pre-defined UIDs, check for permission
15021        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15022            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15023                if (ActivityManager.checkUidPermission(
15024                        INTERACT_ACROSS_USERS,
15025                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15026                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15027                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15028                            + " requests FLAG_SINGLE_USER, but app does not hold "
15029                            + INTERACT_ACROSS_USERS;
15030                    Slog.w(TAG, msg);
15031                    throw new SecurityException(msg);
15032                }
15033                // Permission passed
15034                result = true;
15035            }
15036        } else if ("system".equals(componentProcessName)) {
15037            result = true;
15038        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15039            // Phone app and persistent apps are allowed to export singleuser providers.
15040            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15041                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15042        }
15043        if (DEBUG_MU) {
15044            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15045                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15046        }
15047        return result;
15048    }
15049
15050    /**
15051     * Checks to see if the caller is in the same app as the singleton
15052     * component, or the component is in a special app. It allows special apps
15053     * to export singleton components but prevents exporting singleton
15054     * components for regular apps.
15055     */
15056    boolean isValidSingletonCall(int callingUid, int componentUid) {
15057        int componentAppId = UserHandle.getAppId(componentUid);
15058        return UserHandle.isSameApp(callingUid, componentUid)
15059                || componentAppId == Process.SYSTEM_UID
15060                || componentAppId == Process.PHONE_UID
15061                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15062                        == PackageManager.PERMISSION_GRANTED;
15063    }
15064
15065    public int bindService(IApplicationThread caller, IBinder token,
15066            Intent service, String resolvedType,
15067            IServiceConnection connection, int flags, int userId) {
15068        enforceNotIsolatedCaller("bindService");
15069
15070        // Refuse possible leaked file descriptors
15071        if (service != null && service.hasFileDescriptors() == true) {
15072            throw new IllegalArgumentException("File descriptors passed in Intent");
15073        }
15074
15075        synchronized(this) {
15076            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15077                    connection, flags, userId);
15078        }
15079    }
15080
15081    public boolean unbindService(IServiceConnection connection) {
15082        synchronized (this) {
15083            return mServices.unbindServiceLocked(connection);
15084        }
15085    }
15086
15087    public void publishService(IBinder token, Intent intent, IBinder service) {
15088        // Refuse possible leaked file descriptors
15089        if (intent != null && intent.hasFileDescriptors() == true) {
15090            throw new IllegalArgumentException("File descriptors passed in Intent");
15091        }
15092
15093        synchronized(this) {
15094            if (!(token instanceof ServiceRecord)) {
15095                throw new IllegalArgumentException("Invalid service token");
15096            }
15097            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15098        }
15099    }
15100
15101    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15102        // Refuse possible leaked file descriptors
15103        if (intent != null && intent.hasFileDescriptors() == true) {
15104            throw new IllegalArgumentException("File descriptors passed in Intent");
15105        }
15106
15107        synchronized(this) {
15108            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15109        }
15110    }
15111
15112    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15113        synchronized(this) {
15114            if (!(token instanceof ServiceRecord)) {
15115                throw new IllegalArgumentException("Invalid service token");
15116            }
15117            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15118        }
15119    }
15120
15121    // =========================================================
15122    // BACKUP AND RESTORE
15123    // =========================================================
15124
15125    // Cause the target app to be launched if necessary and its backup agent
15126    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15127    // activity manager to announce its creation.
15128    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15129        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15130        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15131
15132        synchronized(this) {
15133            // !!! TODO: currently no check here that we're already bound
15134            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15135            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15136            synchronized (stats) {
15137                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15138            }
15139
15140            // Backup agent is now in use, its package can't be stopped.
15141            try {
15142                AppGlobals.getPackageManager().setPackageStoppedState(
15143                        app.packageName, false, UserHandle.getUserId(app.uid));
15144            } catch (RemoteException e) {
15145            } catch (IllegalArgumentException e) {
15146                Slog.w(TAG, "Failed trying to unstop package "
15147                        + app.packageName + ": " + e);
15148            }
15149
15150            BackupRecord r = new BackupRecord(ss, app, backupMode);
15151            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15152                    ? new ComponentName(app.packageName, app.backupAgentName)
15153                    : new ComponentName("android", "FullBackupAgent");
15154            // startProcessLocked() returns existing proc's record if it's already running
15155            ProcessRecord proc = startProcessLocked(app.processName, app,
15156                    false, 0, "backup", hostingName, false, false, false);
15157            if (proc == null) {
15158                Slog.e(TAG, "Unable to start backup agent process " + r);
15159                return false;
15160            }
15161
15162            r.app = proc;
15163            mBackupTarget = r;
15164            mBackupAppName = app.packageName;
15165
15166            // Try not to kill the process during backup
15167            updateOomAdjLocked(proc);
15168
15169            // If the process is already attached, schedule the creation of the backup agent now.
15170            // If it is not yet live, this will be done when it attaches to the framework.
15171            if (proc.thread != null) {
15172                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15173                try {
15174                    proc.thread.scheduleCreateBackupAgent(app,
15175                            compatibilityInfoForPackageLocked(app), backupMode);
15176                } catch (RemoteException e) {
15177                    // Will time out on the backup manager side
15178                }
15179            } else {
15180                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15181            }
15182            // Invariants: at this point, the target app process exists and the application
15183            // is either already running or in the process of coming up.  mBackupTarget and
15184            // mBackupAppName describe the app, so that when it binds back to the AM we
15185            // know that it's scheduled for a backup-agent operation.
15186        }
15187
15188        return true;
15189    }
15190
15191    @Override
15192    public void clearPendingBackup() {
15193        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15194        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15195
15196        synchronized (this) {
15197            mBackupTarget = null;
15198            mBackupAppName = null;
15199        }
15200    }
15201
15202    // A backup agent has just come up
15203    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15204        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15205                + " = " + agent);
15206
15207        synchronized(this) {
15208            if (!agentPackageName.equals(mBackupAppName)) {
15209                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15210                return;
15211            }
15212        }
15213
15214        long oldIdent = Binder.clearCallingIdentity();
15215        try {
15216            IBackupManager bm = IBackupManager.Stub.asInterface(
15217                    ServiceManager.getService(Context.BACKUP_SERVICE));
15218            bm.agentConnected(agentPackageName, agent);
15219        } catch (RemoteException e) {
15220            // can't happen; the backup manager service is local
15221        } catch (Exception e) {
15222            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15223            e.printStackTrace();
15224        } finally {
15225            Binder.restoreCallingIdentity(oldIdent);
15226        }
15227    }
15228
15229    // done with this agent
15230    public void unbindBackupAgent(ApplicationInfo appInfo) {
15231        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15232        if (appInfo == null) {
15233            Slog.w(TAG, "unbind backup agent for null app");
15234            return;
15235        }
15236
15237        synchronized(this) {
15238            try {
15239                if (mBackupAppName == null) {
15240                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15241                    return;
15242                }
15243
15244                if (!mBackupAppName.equals(appInfo.packageName)) {
15245                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15246                    return;
15247                }
15248
15249                // Not backing this app up any more; reset its OOM adjustment
15250                final ProcessRecord proc = mBackupTarget.app;
15251                updateOomAdjLocked(proc);
15252
15253                // If the app crashed during backup, 'thread' will be null here
15254                if (proc.thread != null) {
15255                    try {
15256                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15257                                compatibilityInfoForPackageLocked(appInfo));
15258                    } catch (Exception e) {
15259                        Slog.e(TAG, "Exception when unbinding backup agent:");
15260                        e.printStackTrace();
15261                    }
15262                }
15263            } finally {
15264                mBackupTarget = null;
15265                mBackupAppName = null;
15266            }
15267        }
15268    }
15269    // =========================================================
15270    // BROADCASTS
15271    // =========================================================
15272
15273    private final List getStickiesLocked(String action, IntentFilter filter,
15274            List cur, int userId) {
15275        final ContentResolver resolver = mContext.getContentResolver();
15276        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15277        if (stickies == null) {
15278            return cur;
15279        }
15280        final ArrayList<Intent> list = stickies.get(action);
15281        if (list == null) {
15282            return cur;
15283        }
15284        int N = list.size();
15285        for (int i=0; i<N; i++) {
15286            Intent intent = list.get(i);
15287            if (filter.match(resolver, intent, true, TAG) >= 0) {
15288                if (cur == null) {
15289                    cur = new ArrayList<Intent>();
15290                }
15291                cur.add(intent);
15292            }
15293        }
15294        return cur;
15295    }
15296
15297    boolean isPendingBroadcastProcessLocked(int pid) {
15298        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15299                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15300    }
15301
15302    void skipPendingBroadcastLocked(int pid) {
15303            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15304            for (BroadcastQueue queue : mBroadcastQueues) {
15305                queue.skipPendingBroadcastLocked(pid);
15306            }
15307    }
15308
15309    // The app just attached; send any pending broadcasts that it should receive
15310    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15311        boolean didSomething = false;
15312        for (BroadcastQueue queue : mBroadcastQueues) {
15313            didSomething |= queue.sendPendingBroadcastsLocked(app);
15314        }
15315        return didSomething;
15316    }
15317
15318    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15319            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15320        enforceNotIsolatedCaller("registerReceiver");
15321        int callingUid;
15322        int callingPid;
15323        synchronized(this) {
15324            ProcessRecord callerApp = null;
15325            if (caller != null) {
15326                callerApp = getRecordForAppLocked(caller);
15327                if (callerApp == null) {
15328                    throw new SecurityException(
15329                            "Unable to find app for caller " + caller
15330                            + " (pid=" + Binder.getCallingPid()
15331                            + ") when registering receiver " + receiver);
15332                }
15333                if (callerApp.info.uid != Process.SYSTEM_UID &&
15334                        !callerApp.pkgList.containsKey(callerPackage) &&
15335                        !"android".equals(callerPackage)) {
15336                    throw new SecurityException("Given caller package " + callerPackage
15337                            + " is not running in process " + callerApp);
15338                }
15339                callingUid = callerApp.info.uid;
15340                callingPid = callerApp.pid;
15341            } else {
15342                callerPackage = null;
15343                callingUid = Binder.getCallingUid();
15344                callingPid = Binder.getCallingPid();
15345            }
15346
15347            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15348                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15349
15350            List allSticky = null;
15351
15352            // Look for any matching sticky broadcasts...
15353            Iterator actions = filter.actionsIterator();
15354            if (actions != null) {
15355                while (actions.hasNext()) {
15356                    String action = (String)actions.next();
15357                    allSticky = getStickiesLocked(action, filter, allSticky,
15358                            UserHandle.USER_ALL);
15359                    allSticky = getStickiesLocked(action, filter, allSticky,
15360                            UserHandle.getUserId(callingUid));
15361                }
15362            } else {
15363                allSticky = getStickiesLocked(null, filter, allSticky,
15364                        UserHandle.USER_ALL);
15365                allSticky = getStickiesLocked(null, filter, allSticky,
15366                        UserHandle.getUserId(callingUid));
15367            }
15368
15369            // The first sticky in the list is returned directly back to
15370            // the client.
15371            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15372
15373            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15374                    + ": " + sticky);
15375
15376            if (receiver == null) {
15377                return sticky;
15378            }
15379
15380            ReceiverList rl
15381                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15382            if (rl == null) {
15383                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15384                        userId, receiver);
15385                if (rl.app != null) {
15386                    rl.app.receivers.add(rl);
15387                } else {
15388                    try {
15389                        receiver.asBinder().linkToDeath(rl, 0);
15390                    } catch (RemoteException e) {
15391                        return sticky;
15392                    }
15393                    rl.linkedToDeath = true;
15394                }
15395                mRegisteredReceivers.put(receiver.asBinder(), rl);
15396            } else if (rl.uid != callingUid) {
15397                throw new IllegalArgumentException(
15398                        "Receiver requested to register for uid " + callingUid
15399                        + " was previously registered for uid " + rl.uid);
15400            } else if (rl.pid != callingPid) {
15401                throw new IllegalArgumentException(
15402                        "Receiver requested to register for pid " + callingPid
15403                        + " was previously registered for pid " + rl.pid);
15404            } else if (rl.userId != userId) {
15405                throw new IllegalArgumentException(
15406                        "Receiver requested to register for user " + userId
15407                        + " was previously registered for user " + rl.userId);
15408            }
15409            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15410                    permission, callingUid, userId);
15411            rl.add(bf);
15412            if (!bf.debugCheck()) {
15413                Slog.w(TAG, "==> For Dynamic broadast");
15414            }
15415            mReceiverResolver.addFilter(bf);
15416
15417            // Enqueue broadcasts for all existing stickies that match
15418            // this filter.
15419            if (allSticky != null) {
15420                ArrayList receivers = new ArrayList();
15421                receivers.add(bf);
15422
15423                int N = allSticky.size();
15424                for (int i=0; i<N; i++) {
15425                    Intent intent = (Intent)allSticky.get(i);
15426                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15427                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15428                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15429                            null, null, false, true, true, -1);
15430                    queue.enqueueParallelBroadcastLocked(r);
15431                    queue.scheduleBroadcastsLocked();
15432                }
15433            }
15434
15435            return sticky;
15436        }
15437    }
15438
15439    public void unregisterReceiver(IIntentReceiver receiver) {
15440        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15441
15442        final long origId = Binder.clearCallingIdentity();
15443        try {
15444            boolean doTrim = false;
15445
15446            synchronized(this) {
15447                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15448                if (rl != null) {
15449                    if (rl.curBroadcast != null) {
15450                        BroadcastRecord r = rl.curBroadcast;
15451                        final boolean doNext = finishReceiverLocked(
15452                                receiver.asBinder(), r.resultCode, r.resultData,
15453                                r.resultExtras, r.resultAbort);
15454                        if (doNext) {
15455                            doTrim = true;
15456                            r.queue.processNextBroadcast(false);
15457                        }
15458                    }
15459
15460                    if (rl.app != null) {
15461                        rl.app.receivers.remove(rl);
15462                    }
15463                    removeReceiverLocked(rl);
15464                    if (rl.linkedToDeath) {
15465                        rl.linkedToDeath = false;
15466                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15467                    }
15468                }
15469            }
15470
15471            // If we actually concluded any broadcasts, we might now be able
15472            // to trim the recipients' apps from our working set
15473            if (doTrim) {
15474                trimApplications();
15475                return;
15476            }
15477
15478        } finally {
15479            Binder.restoreCallingIdentity(origId);
15480        }
15481    }
15482
15483    void removeReceiverLocked(ReceiverList rl) {
15484        mRegisteredReceivers.remove(rl.receiver.asBinder());
15485        int N = rl.size();
15486        for (int i=0; i<N; i++) {
15487            mReceiverResolver.removeFilter(rl.get(i));
15488        }
15489    }
15490
15491    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15492        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15493            ProcessRecord r = mLruProcesses.get(i);
15494            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15495                try {
15496                    r.thread.dispatchPackageBroadcast(cmd, packages);
15497                } catch (RemoteException ex) {
15498                }
15499            }
15500        }
15501    }
15502
15503    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15504            int callingUid, int[] users) {
15505        List<ResolveInfo> receivers = null;
15506        try {
15507            HashSet<ComponentName> singleUserReceivers = null;
15508            boolean scannedFirstReceivers = false;
15509            for (int user : users) {
15510                // Skip users that have Shell restrictions
15511                if (callingUid == Process.SHELL_UID
15512                        && getUserManagerLocked().hasUserRestriction(
15513                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15514                    continue;
15515                }
15516                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15517                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15518                if (user != 0 && newReceivers != null) {
15519                    // If this is not the primary user, we need to check for
15520                    // any receivers that should be filtered out.
15521                    for (int i=0; i<newReceivers.size(); i++) {
15522                        ResolveInfo ri = newReceivers.get(i);
15523                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15524                            newReceivers.remove(i);
15525                            i--;
15526                        }
15527                    }
15528                }
15529                if (newReceivers != null && newReceivers.size() == 0) {
15530                    newReceivers = null;
15531                }
15532                if (receivers == null) {
15533                    receivers = newReceivers;
15534                } else if (newReceivers != null) {
15535                    // We need to concatenate the additional receivers
15536                    // found with what we have do far.  This would be easy,
15537                    // but we also need to de-dup any receivers that are
15538                    // singleUser.
15539                    if (!scannedFirstReceivers) {
15540                        // Collect any single user receivers we had already retrieved.
15541                        scannedFirstReceivers = true;
15542                        for (int i=0; i<receivers.size(); i++) {
15543                            ResolveInfo ri = receivers.get(i);
15544                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15545                                ComponentName cn = new ComponentName(
15546                                        ri.activityInfo.packageName, ri.activityInfo.name);
15547                                if (singleUserReceivers == null) {
15548                                    singleUserReceivers = new HashSet<ComponentName>();
15549                                }
15550                                singleUserReceivers.add(cn);
15551                            }
15552                        }
15553                    }
15554                    // Add the new results to the existing results, tracking
15555                    // and de-dupping single user receivers.
15556                    for (int i=0; i<newReceivers.size(); i++) {
15557                        ResolveInfo ri = newReceivers.get(i);
15558                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15559                            ComponentName cn = new ComponentName(
15560                                    ri.activityInfo.packageName, ri.activityInfo.name);
15561                            if (singleUserReceivers == null) {
15562                                singleUserReceivers = new HashSet<ComponentName>();
15563                            }
15564                            if (!singleUserReceivers.contains(cn)) {
15565                                singleUserReceivers.add(cn);
15566                                receivers.add(ri);
15567                            }
15568                        } else {
15569                            receivers.add(ri);
15570                        }
15571                    }
15572                }
15573            }
15574        } catch (RemoteException ex) {
15575            // pm is in same process, this will never happen.
15576        }
15577        return receivers;
15578    }
15579
15580    private final int broadcastIntentLocked(ProcessRecord callerApp,
15581            String callerPackage, Intent intent, String resolvedType,
15582            IIntentReceiver resultTo, int resultCode, String resultData,
15583            Bundle map, String requiredPermission, int appOp,
15584            boolean ordered, boolean sticky, int callingPid, int callingUid,
15585            int userId) {
15586        intent = new Intent(intent);
15587
15588        // By default broadcasts do not go to stopped apps.
15589        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15590
15591        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15592            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15593            + " ordered=" + ordered + " userid=" + userId);
15594        if ((resultTo != null) && !ordered) {
15595            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15596        }
15597
15598        userId = handleIncomingUser(callingPid, callingUid, userId,
15599                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15600
15601        // Make sure that the user who is receiving this broadcast is started.
15602        // If not, we will just skip it.
15603
15604        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15605            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15606                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15607                Slog.w(TAG, "Skipping broadcast of " + intent
15608                        + ": user " + userId + " is stopped");
15609                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15610            }
15611        }
15612
15613        /*
15614         * Prevent non-system code (defined here to be non-persistent
15615         * processes) from sending protected broadcasts.
15616         */
15617        int callingAppId = UserHandle.getAppId(callingUid);
15618        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15619            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15620            || callingAppId == Process.NFC_UID || callingUid == 0) {
15621            // Always okay.
15622        } else if (callerApp == null || !callerApp.persistent) {
15623            try {
15624                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15625                        intent.getAction())) {
15626                    String msg = "Permission Denial: not allowed to send broadcast "
15627                            + intent.getAction() + " from pid="
15628                            + callingPid + ", uid=" + callingUid;
15629                    Slog.w(TAG, msg);
15630                    throw new SecurityException(msg);
15631                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15632                    // Special case for compatibility: we don't want apps to send this,
15633                    // but historically it has not been protected and apps may be using it
15634                    // to poke their own app widget.  So, instead of making it protected,
15635                    // just limit it to the caller.
15636                    if (callerApp == null) {
15637                        String msg = "Permission Denial: not allowed to send broadcast "
15638                                + intent.getAction() + " from unknown caller.";
15639                        Slog.w(TAG, msg);
15640                        throw new SecurityException(msg);
15641                    } else if (intent.getComponent() != null) {
15642                        // They are good enough to send to an explicit component...  verify
15643                        // it is being sent to the calling app.
15644                        if (!intent.getComponent().getPackageName().equals(
15645                                callerApp.info.packageName)) {
15646                            String msg = "Permission Denial: not allowed to send broadcast "
15647                                    + intent.getAction() + " to "
15648                                    + intent.getComponent().getPackageName() + " from "
15649                                    + callerApp.info.packageName;
15650                            Slog.w(TAG, msg);
15651                            throw new SecurityException(msg);
15652                        }
15653                    } else {
15654                        // Limit broadcast to their own package.
15655                        intent.setPackage(callerApp.info.packageName);
15656                    }
15657                }
15658            } catch (RemoteException e) {
15659                Slog.w(TAG, "Remote exception", e);
15660                return ActivityManager.BROADCAST_SUCCESS;
15661            }
15662        }
15663
15664        // Handle special intents: if this broadcast is from the package
15665        // manager about a package being removed, we need to remove all of
15666        // its activities from the history stack.
15667        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15668                intent.getAction());
15669        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15670                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15671                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15672                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15673                || uidRemoved) {
15674            if (checkComponentPermission(
15675                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15676                    callingPid, callingUid, -1, true)
15677                    == PackageManager.PERMISSION_GRANTED) {
15678                if (uidRemoved) {
15679                    final Bundle intentExtras = intent.getExtras();
15680                    final int uid = intentExtras != null
15681                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15682                    if (uid >= 0) {
15683                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15684                        synchronized (bs) {
15685                            bs.removeUidStatsLocked(uid);
15686                        }
15687                        mAppOpsService.uidRemoved(uid);
15688                    }
15689                } else {
15690                    // If resources are unavailable just force stop all
15691                    // those packages and flush the attribute cache as well.
15692                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15693                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15694                        if (list != null && (list.length > 0)) {
15695                            for (String pkg : list) {
15696                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15697                                        "storage unmount");
15698                            }
15699                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15700                            sendPackageBroadcastLocked(
15701                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15702                        }
15703                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15704                            intent.getAction())) {
15705                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15706                    } else {
15707                        Uri data = intent.getData();
15708                        String ssp;
15709                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15710                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15711                                    intent.getAction());
15712                            boolean fullUninstall = removed &&
15713                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15714                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15715                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15716                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15717                                        false, fullUninstall, userId,
15718                                        removed ? "pkg removed" : "pkg changed");
15719                            }
15720                            if (removed) {
15721                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15722                                        new String[] {ssp}, userId);
15723                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15724                                    mAppOpsService.packageRemoved(
15725                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15726
15727                                    // Remove all permissions granted from/to this package
15728                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15729                                }
15730                            }
15731                        }
15732                    }
15733                }
15734            } else {
15735                String msg = "Permission Denial: " + intent.getAction()
15736                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15737                        + ", uid=" + callingUid + ")"
15738                        + " requires "
15739                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15740                Slog.w(TAG, msg);
15741                throw new SecurityException(msg);
15742            }
15743
15744        // Special case for adding a package: by default turn on compatibility
15745        // mode.
15746        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15747            Uri data = intent.getData();
15748            String ssp;
15749            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15750                mCompatModePackages.handlePackageAddedLocked(ssp,
15751                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15752            }
15753        }
15754
15755        /*
15756         * If this is the time zone changed action, queue up a message that will reset the timezone
15757         * of all currently running processes. This message will get queued up before the broadcast
15758         * happens.
15759         */
15760        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15761            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15762        }
15763
15764        /*
15765         * If the user set the time, let all running processes know.
15766         */
15767        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15768            final int is24Hour = intent.getBooleanExtra(
15769                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15770            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15771            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15772            synchronized (stats) {
15773                stats.noteCurrentTimeChangedLocked();
15774            }
15775        }
15776
15777        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15778            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15779        }
15780
15781        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15782            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15783            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15784        }
15785
15786        // Add to the sticky list if requested.
15787        if (sticky) {
15788            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15789                    callingPid, callingUid)
15790                    != PackageManager.PERMISSION_GRANTED) {
15791                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15792                        + callingPid + ", uid=" + callingUid
15793                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15794                Slog.w(TAG, msg);
15795                throw new SecurityException(msg);
15796            }
15797            if (requiredPermission != null) {
15798                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15799                        + " and enforce permission " + requiredPermission);
15800                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15801            }
15802            if (intent.getComponent() != null) {
15803                throw new SecurityException(
15804                        "Sticky broadcasts can't target a specific component");
15805            }
15806            // We use userId directly here, since the "all" target is maintained
15807            // as a separate set of sticky broadcasts.
15808            if (userId != UserHandle.USER_ALL) {
15809                // But first, if this is not a broadcast to all users, then
15810                // make sure it doesn't conflict with an existing broadcast to
15811                // all users.
15812                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15813                        UserHandle.USER_ALL);
15814                if (stickies != null) {
15815                    ArrayList<Intent> list = stickies.get(intent.getAction());
15816                    if (list != null) {
15817                        int N = list.size();
15818                        int i;
15819                        for (i=0; i<N; i++) {
15820                            if (intent.filterEquals(list.get(i))) {
15821                                throw new IllegalArgumentException(
15822                                        "Sticky broadcast " + intent + " for user "
15823                                        + userId + " conflicts with existing global broadcast");
15824                            }
15825                        }
15826                    }
15827                }
15828            }
15829            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15830            if (stickies == null) {
15831                stickies = new ArrayMap<String, ArrayList<Intent>>();
15832                mStickyBroadcasts.put(userId, stickies);
15833            }
15834            ArrayList<Intent> list = stickies.get(intent.getAction());
15835            if (list == null) {
15836                list = new ArrayList<Intent>();
15837                stickies.put(intent.getAction(), list);
15838            }
15839            int N = list.size();
15840            int i;
15841            for (i=0; i<N; i++) {
15842                if (intent.filterEquals(list.get(i))) {
15843                    // This sticky already exists, replace it.
15844                    list.set(i, new Intent(intent));
15845                    break;
15846                }
15847            }
15848            if (i >= N) {
15849                list.add(new Intent(intent));
15850            }
15851        }
15852
15853        int[] users;
15854        if (userId == UserHandle.USER_ALL) {
15855            // Caller wants broadcast to go to all started users.
15856            users = mStartedUserArray;
15857        } else {
15858            // Caller wants broadcast to go to one specific user.
15859            users = new int[] {userId};
15860        }
15861
15862        // Figure out who all will receive this broadcast.
15863        List receivers = null;
15864        List<BroadcastFilter> registeredReceivers = null;
15865        // Need to resolve the intent to interested receivers...
15866        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15867                 == 0) {
15868            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15869        }
15870        if (intent.getComponent() == null) {
15871            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15872                // Query one target user at a time, excluding shell-restricted users
15873                UserManagerService ums = getUserManagerLocked();
15874                for (int i = 0; i < users.length; i++) {
15875                    if (ums.hasUserRestriction(
15876                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15877                        continue;
15878                    }
15879                    List<BroadcastFilter> registeredReceiversForUser =
15880                            mReceiverResolver.queryIntent(intent,
15881                                    resolvedType, false, users[i]);
15882                    if (registeredReceivers == null) {
15883                        registeredReceivers = registeredReceiversForUser;
15884                    } else if (registeredReceiversForUser != null) {
15885                        registeredReceivers.addAll(registeredReceiversForUser);
15886                    }
15887                }
15888            } else {
15889                registeredReceivers = mReceiverResolver.queryIntent(intent,
15890                        resolvedType, false, userId);
15891            }
15892        }
15893
15894        final boolean replacePending =
15895                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15896
15897        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15898                + " replacePending=" + replacePending);
15899
15900        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15901        if (!ordered && NR > 0) {
15902            // If we are not serializing this broadcast, then send the
15903            // registered receivers separately so they don't wait for the
15904            // components to be launched.
15905            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15906            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15907                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15908                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15909                    ordered, sticky, false, userId);
15910            if (DEBUG_BROADCAST) Slog.v(
15911                    TAG, "Enqueueing parallel broadcast " + r);
15912            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15913            if (!replaced) {
15914                queue.enqueueParallelBroadcastLocked(r);
15915                queue.scheduleBroadcastsLocked();
15916            }
15917            registeredReceivers = null;
15918            NR = 0;
15919        }
15920
15921        // Merge into one list.
15922        int ir = 0;
15923        if (receivers != null) {
15924            // A special case for PACKAGE_ADDED: do not allow the package
15925            // being added to see this broadcast.  This prevents them from
15926            // using this as a back door to get run as soon as they are
15927            // installed.  Maybe in the future we want to have a special install
15928            // broadcast or such for apps, but we'd like to deliberately make
15929            // this decision.
15930            String skipPackages[] = null;
15931            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15932                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15933                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15934                Uri data = intent.getData();
15935                if (data != null) {
15936                    String pkgName = data.getSchemeSpecificPart();
15937                    if (pkgName != null) {
15938                        skipPackages = new String[] { pkgName };
15939                    }
15940                }
15941            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15942                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15943            }
15944            if (skipPackages != null && (skipPackages.length > 0)) {
15945                for (String skipPackage : skipPackages) {
15946                    if (skipPackage != null) {
15947                        int NT = receivers.size();
15948                        for (int it=0; it<NT; it++) {
15949                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15950                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15951                                receivers.remove(it);
15952                                it--;
15953                                NT--;
15954                            }
15955                        }
15956                    }
15957                }
15958            }
15959
15960            int NT = receivers != null ? receivers.size() : 0;
15961            int it = 0;
15962            ResolveInfo curt = null;
15963            BroadcastFilter curr = null;
15964            while (it < NT && ir < NR) {
15965                if (curt == null) {
15966                    curt = (ResolveInfo)receivers.get(it);
15967                }
15968                if (curr == null) {
15969                    curr = registeredReceivers.get(ir);
15970                }
15971                if (curr.getPriority() >= curt.priority) {
15972                    // Insert this broadcast record into the final list.
15973                    receivers.add(it, curr);
15974                    ir++;
15975                    curr = null;
15976                    it++;
15977                    NT++;
15978                } else {
15979                    // Skip to the next ResolveInfo in the final list.
15980                    it++;
15981                    curt = null;
15982                }
15983            }
15984        }
15985        while (ir < NR) {
15986            if (receivers == null) {
15987                receivers = new ArrayList();
15988            }
15989            receivers.add(registeredReceivers.get(ir));
15990            ir++;
15991        }
15992
15993        if ((receivers != null && receivers.size() > 0)
15994                || resultTo != null) {
15995            BroadcastQueue queue = broadcastQueueForIntent(intent);
15996            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15997                    callerPackage, callingPid, callingUid, resolvedType,
15998                    requiredPermission, appOp, receivers, resultTo, resultCode,
15999                    resultData, map, ordered, sticky, false, userId);
16000            if (DEBUG_BROADCAST) Slog.v(
16001                    TAG, "Enqueueing ordered broadcast " + r
16002                    + ": prev had " + queue.mOrderedBroadcasts.size());
16003            if (DEBUG_BROADCAST) {
16004                int seq = r.intent.getIntExtra("seq", -1);
16005                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16006            }
16007            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16008            if (!replaced) {
16009                queue.enqueueOrderedBroadcastLocked(r);
16010                queue.scheduleBroadcastsLocked();
16011            }
16012        }
16013
16014        return ActivityManager.BROADCAST_SUCCESS;
16015    }
16016
16017    final Intent verifyBroadcastLocked(Intent intent) {
16018        // Refuse possible leaked file descriptors
16019        if (intent != null && intent.hasFileDescriptors() == true) {
16020            throw new IllegalArgumentException("File descriptors passed in Intent");
16021        }
16022
16023        int flags = intent.getFlags();
16024
16025        if (!mProcessesReady) {
16026            // if the caller really truly claims to know what they're doing, go
16027            // ahead and allow the broadcast without launching any receivers
16028            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16029                intent = new Intent(intent);
16030                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16031            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16032                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16033                        + " before boot completion");
16034                throw new IllegalStateException("Cannot broadcast before boot completed");
16035            }
16036        }
16037
16038        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16039            throw new IllegalArgumentException(
16040                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16041        }
16042
16043        return intent;
16044    }
16045
16046    public final int broadcastIntent(IApplicationThread caller,
16047            Intent intent, String resolvedType, IIntentReceiver resultTo,
16048            int resultCode, String resultData, Bundle map,
16049            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16050        enforceNotIsolatedCaller("broadcastIntent");
16051        synchronized(this) {
16052            intent = verifyBroadcastLocked(intent);
16053
16054            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16055            final int callingPid = Binder.getCallingPid();
16056            final int callingUid = Binder.getCallingUid();
16057            final long origId = Binder.clearCallingIdentity();
16058            int res = broadcastIntentLocked(callerApp,
16059                    callerApp != null ? callerApp.info.packageName : null,
16060                    intent, resolvedType, resultTo,
16061                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16062                    callingPid, callingUid, userId);
16063            Binder.restoreCallingIdentity(origId);
16064            return res;
16065        }
16066    }
16067
16068    int broadcastIntentInPackage(String packageName, int uid,
16069            Intent intent, String resolvedType, IIntentReceiver resultTo,
16070            int resultCode, String resultData, Bundle map,
16071            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16072        synchronized(this) {
16073            intent = verifyBroadcastLocked(intent);
16074
16075            final long origId = Binder.clearCallingIdentity();
16076            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16077                    resultTo, resultCode, resultData, map, requiredPermission,
16078                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16079            Binder.restoreCallingIdentity(origId);
16080            return res;
16081        }
16082    }
16083
16084    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16085        // Refuse possible leaked file descriptors
16086        if (intent != null && intent.hasFileDescriptors() == true) {
16087            throw new IllegalArgumentException("File descriptors passed in Intent");
16088        }
16089
16090        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16091                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16092
16093        synchronized(this) {
16094            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16095                    != PackageManager.PERMISSION_GRANTED) {
16096                String msg = "Permission Denial: unbroadcastIntent() from pid="
16097                        + Binder.getCallingPid()
16098                        + ", uid=" + Binder.getCallingUid()
16099                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16100                Slog.w(TAG, msg);
16101                throw new SecurityException(msg);
16102            }
16103            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16104            if (stickies != null) {
16105                ArrayList<Intent> list = stickies.get(intent.getAction());
16106                if (list != null) {
16107                    int N = list.size();
16108                    int i;
16109                    for (i=0; i<N; i++) {
16110                        if (intent.filterEquals(list.get(i))) {
16111                            list.remove(i);
16112                            break;
16113                        }
16114                    }
16115                    if (list.size() <= 0) {
16116                        stickies.remove(intent.getAction());
16117                    }
16118                }
16119                if (stickies.size() <= 0) {
16120                    mStickyBroadcasts.remove(userId);
16121                }
16122            }
16123        }
16124    }
16125
16126    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16127            String resultData, Bundle resultExtras, boolean resultAbort) {
16128        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16129        if (r == null) {
16130            Slog.w(TAG, "finishReceiver called but not found on queue");
16131            return false;
16132        }
16133
16134        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16135    }
16136
16137    void backgroundServicesFinishedLocked(int userId) {
16138        for (BroadcastQueue queue : mBroadcastQueues) {
16139            queue.backgroundServicesFinishedLocked(userId);
16140        }
16141    }
16142
16143    public void finishReceiver(IBinder who, int resultCode, String resultData,
16144            Bundle resultExtras, boolean resultAbort) {
16145        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16146
16147        // Refuse possible leaked file descriptors
16148        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16149            throw new IllegalArgumentException("File descriptors passed in Bundle");
16150        }
16151
16152        final long origId = Binder.clearCallingIdentity();
16153        try {
16154            boolean doNext = false;
16155            BroadcastRecord r;
16156
16157            synchronized(this) {
16158                r = broadcastRecordForReceiverLocked(who);
16159                if (r != null) {
16160                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16161                        resultData, resultExtras, resultAbort, true);
16162                }
16163            }
16164
16165            if (doNext) {
16166                r.queue.processNextBroadcast(false);
16167            }
16168            trimApplications();
16169        } finally {
16170            Binder.restoreCallingIdentity(origId);
16171        }
16172    }
16173
16174    // =========================================================
16175    // INSTRUMENTATION
16176    // =========================================================
16177
16178    public boolean startInstrumentation(ComponentName className,
16179            String profileFile, int flags, Bundle arguments,
16180            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16181            int userId, String abiOverride) {
16182        enforceNotIsolatedCaller("startInstrumentation");
16183        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16184                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16185        // Refuse possible leaked file descriptors
16186        if (arguments != null && arguments.hasFileDescriptors()) {
16187            throw new IllegalArgumentException("File descriptors passed in Bundle");
16188        }
16189
16190        synchronized(this) {
16191            InstrumentationInfo ii = null;
16192            ApplicationInfo ai = null;
16193            try {
16194                ii = mContext.getPackageManager().getInstrumentationInfo(
16195                    className, STOCK_PM_FLAGS);
16196                ai = AppGlobals.getPackageManager().getApplicationInfo(
16197                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16198            } catch (PackageManager.NameNotFoundException e) {
16199            } catch (RemoteException e) {
16200            }
16201            if (ii == null) {
16202                reportStartInstrumentationFailure(watcher, className,
16203                        "Unable to find instrumentation info for: " + className);
16204                return false;
16205            }
16206            if (ai == null) {
16207                reportStartInstrumentationFailure(watcher, className,
16208                        "Unable to find instrumentation target package: " + ii.targetPackage);
16209                return false;
16210            }
16211
16212            int match = mContext.getPackageManager().checkSignatures(
16213                    ii.targetPackage, ii.packageName);
16214            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16215                String msg = "Permission Denial: starting instrumentation "
16216                        + className + " from pid="
16217                        + Binder.getCallingPid()
16218                        + ", uid=" + Binder.getCallingPid()
16219                        + " not allowed because package " + ii.packageName
16220                        + " does not have a signature matching the target "
16221                        + ii.targetPackage;
16222                reportStartInstrumentationFailure(watcher, className, msg);
16223                throw new SecurityException(msg);
16224            }
16225
16226            final long origId = Binder.clearCallingIdentity();
16227            // Instrumentation can kill and relaunch even persistent processes
16228            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16229                    "start instr");
16230            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16231            app.instrumentationClass = className;
16232            app.instrumentationInfo = ai;
16233            app.instrumentationProfileFile = profileFile;
16234            app.instrumentationArguments = arguments;
16235            app.instrumentationWatcher = watcher;
16236            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16237            app.instrumentationResultClass = className;
16238            Binder.restoreCallingIdentity(origId);
16239        }
16240
16241        return true;
16242    }
16243
16244    /**
16245     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16246     * error to the logs, but if somebody is watching, send the report there too.  This enables
16247     * the "am" command to report errors with more information.
16248     *
16249     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16250     * @param cn The component name of the instrumentation.
16251     * @param report The error report.
16252     */
16253    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16254            ComponentName cn, String report) {
16255        Slog.w(TAG, report);
16256        try {
16257            if (watcher != null) {
16258                Bundle results = new Bundle();
16259                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16260                results.putString("Error", report);
16261                watcher.instrumentationStatus(cn, -1, results);
16262            }
16263        } catch (RemoteException e) {
16264            Slog.w(TAG, e);
16265        }
16266    }
16267
16268    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16269        if (app.instrumentationWatcher != null) {
16270            try {
16271                // NOTE:  IInstrumentationWatcher *must* be oneway here
16272                app.instrumentationWatcher.instrumentationFinished(
16273                    app.instrumentationClass,
16274                    resultCode,
16275                    results);
16276            } catch (RemoteException e) {
16277            }
16278        }
16279        if (app.instrumentationUiAutomationConnection != null) {
16280            try {
16281                app.instrumentationUiAutomationConnection.shutdown();
16282            } catch (RemoteException re) {
16283                /* ignore */
16284            }
16285            // Only a UiAutomation can set this flag and now that
16286            // it is finished we make sure it is reset to its default.
16287            mUserIsMonkey = false;
16288        }
16289        app.instrumentationWatcher = null;
16290        app.instrumentationUiAutomationConnection = null;
16291        app.instrumentationClass = null;
16292        app.instrumentationInfo = null;
16293        app.instrumentationProfileFile = null;
16294        app.instrumentationArguments = null;
16295
16296        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16297                "finished inst");
16298    }
16299
16300    public void finishInstrumentation(IApplicationThread target,
16301            int resultCode, Bundle results) {
16302        int userId = UserHandle.getCallingUserId();
16303        // Refuse possible leaked file descriptors
16304        if (results != null && results.hasFileDescriptors()) {
16305            throw new IllegalArgumentException("File descriptors passed in Intent");
16306        }
16307
16308        synchronized(this) {
16309            ProcessRecord app = getRecordForAppLocked(target);
16310            if (app == null) {
16311                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16312                return;
16313            }
16314            final long origId = Binder.clearCallingIdentity();
16315            finishInstrumentationLocked(app, resultCode, results);
16316            Binder.restoreCallingIdentity(origId);
16317        }
16318    }
16319
16320    // =========================================================
16321    // CONFIGURATION
16322    // =========================================================
16323
16324    public ConfigurationInfo getDeviceConfigurationInfo() {
16325        ConfigurationInfo config = new ConfigurationInfo();
16326        synchronized (this) {
16327            config.reqTouchScreen = mConfiguration.touchscreen;
16328            config.reqKeyboardType = mConfiguration.keyboard;
16329            config.reqNavigation = mConfiguration.navigation;
16330            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16331                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16332                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16333            }
16334            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16335                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16336                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16337            }
16338            config.reqGlEsVersion = GL_ES_VERSION;
16339        }
16340        return config;
16341    }
16342
16343    ActivityStack getFocusedStack() {
16344        return mStackSupervisor.getFocusedStack();
16345    }
16346
16347    public Configuration getConfiguration() {
16348        Configuration ci;
16349        synchronized(this) {
16350            ci = new Configuration(mConfiguration);
16351        }
16352        return ci;
16353    }
16354
16355    public void updatePersistentConfiguration(Configuration values) {
16356        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16357                "updateConfiguration()");
16358        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16359                "updateConfiguration()");
16360        if (values == null) {
16361            throw new NullPointerException("Configuration must not be null");
16362        }
16363
16364        synchronized(this) {
16365            final long origId = Binder.clearCallingIdentity();
16366            updateConfigurationLocked(values, null, true, false);
16367            Binder.restoreCallingIdentity(origId);
16368        }
16369    }
16370
16371    public void updateConfiguration(Configuration values) {
16372        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16373                "updateConfiguration()");
16374
16375        synchronized(this) {
16376            if (values == null && mWindowManager != null) {
16377                // sentinel: fetch the current configuration from the window manager
16378                values = mWindowManager.computeNewConfiguration();
16379            }
16380
16381            if (mWindowManager != null) {
16382                mProcessList.applyDisplaySize(mWindowManager);
16383            }
16384
16385            final long origId = Binder.clearCallingIdentity();
16386            if (values != null) {
16387                Settings.System.clearConfiguration(values);
16388            }
16389            updateConfigurationLocked(values, null, false, false);
16390            Binder.restoreCallingIdentity(origId);
16391        }
16392    }
16393
16394    /**
16395     * Do either or both things: (1) change the current configuration, and (2)
16396     * make sure the given activity is running with the (now) current
16397     * configuration.  Returns true if the activity has been left running, or
16398     * false if <var>starting</var> is being destroyed to match the new
16399     * configuration.
16400     * @param persistent TODO
16401     */
16402    boolean updateConfigurationLocked(Configuration values,
16403            ActivityRecord starting, boolean persistent, boolean initLocale) {
16404        int changes = 0;
16405
16406        if (values != null) {
16407            Configuration newConfig = new Configuration(mConfiguration);
16408            changes = newConfig.updateFrom(values);
16409            if (changes != 0) {
16410                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16411                    Slog.i(TAG, "Updating configuration to: " + values);
16412                }
16413
16414                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16415
16416                if (values.locale != null && !initLocale) {
16417                    saveLocaleLocked(values.locale,
16418                                     !values.locale.equals(mConfiguration.locale),
16419                                     values.userSetLocale);
16420                }
16421
16422                mConfigurationSeq++;
16423                if (mConfigurationSeq <= 0) {
16424                    mConfigurationSeq = 1;
16425                }
16426                newConfig.seq = mConfigurationSeq;
16427                mConfiguration = newConfig;
16428                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16429                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16430                //mUsageStatsService.noteStartConfig(newConfig);
16431
16432                final Configuration configCopy = new Configuration(mConfiguration);
16433
16434                // TODO: If our config changes, should we auto dismiss any currently
16435                // showing dialogs?
16436                mShowDialogs = shouldShowDialogs(newConfig);
16437
16438                AttributeCache ac = AttributeCache.instance();
16439                if (ac != null) {
16440                    ac.updateConfiguration(configCopy);
16441                }
16442
16443                // Make sure all resources in our process are updated
16444                // right now, so that anyone who is going to retrieve
16445                // resource values after we return will be sure to get
16446                // the new ones.  This is especially important during
16447                // boot, where the first config change needs to guarantee
16448                // all resources have that config before following boot
16449                // code is executed.
16450                mSystemThread.applyConfigurationToResources(configCopy);
16451
16452                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16453                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16454                    msg.obj = new Configuration(configCopy);
16455                    mHandler.sendMessage(msg);
16456                }
16457
16458                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16459                    ProcessRecord app = mLruProcesses.get(i);
16460                    try {
16461                        if (app.thread != null) {
16462                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16463                                    + app.processName + " new config " + mConfiguration);
16464                            app.thread.scheduleConfigurationChanged(configCopy);
16465                        }
16466                    } catch (Exception e) {
16467                    }
16468                }
16469                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16470                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16471                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16472                        | Intent.FLAG_RECEIVER_FOREGROUND);
16473                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16474                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16475                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16476                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16477                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16478                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16479                    broadcastIntentLocked(null, null, intent,
16480                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16481                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16482                }
16483            }
16484        }
16485
16486        boolean kept = true;
16487        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16488        // mainStack is null during startup.
16489        if (mainStack != null) {
16490            if (changes != 0 && starting == null) {
16491                // If the configuration changed, and the caller is not already
16492                // in the process of starting an activity, then find the top
16493                // activity to check if its configuration needs to change.
16494                starting = mainStack.topRunningActivityLocked(null);
16495            }
16496
16497            if (starting != null) {
16498                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16499                // And we need to make sure at this point that all other activities
16500                // are made visible with the correct configuration.
16501                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16502            }
16503        }
16504
16505        if (values != null && mWindowManager != null) {
16506            mWindowManager.setNewConfiguration(mConfiguration);
16507        }
16508
16509        return kept;
16510    }
16511
16512    /**
16513     * Decide based on the configuration whether we should shouw the ANR,
16514     * crash, etc dialogs.  The idea is that if there is no affordnace to
16515     * press the on-screen buttons, we shouldn't show the dialog.
16516     *
16517     * A thought: SystemUI might also want to get told about this, the Power
16518     * dialog / global actions also might want different behaviors.
16519     */
16520    private static final boolean shouldShowDialogs(Configuration config) {
16521        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16522                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16523    }
16524
16525    /**
16526     * Save the locale.  You must be inside a synchronized (this) block.
16527     */
16528    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16529        if(isDiff) {
16530            SystemProperties.set("user.language", l.getLanguage());
16531            SystemProperties.set("user.region", l.getCountry());
16532        }
16533
16534        if(isPersist) {
16535            SystemProperties.set("persist.sys.language", l.getLanguage());
16536            SystemProperties.set("persist.sys.country", l.getCountry());
16537            SystemProperties.set("persist.sys.localevar", l.getVariant());
16538
16539            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16540        }
16541    }
16542
16543    @Override
16544    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16545        synchronized (this) {
16546            ActivityRecord srec = ActivityRecord.forToken(token);
16547            if (srec.task != null && srec.task.stack != null) {
16548                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16549            }
16550        }
16551        return false;
16552    }
16553
16554    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16555            Intent resultData) {
16556
16557        synchronized (this) {
16558            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16559            if (stack != null) {
16560                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16561            }
16562            return false;
16563        }
16564    }
16565
16566    public int getLaunchedFromUid(IBinder activityToken) {
16567        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16568        if (srec == null) {
16569            return -1;
16570        }
16571        return srec.launchedFromUid;
16572    }
16573
16574    public String getLaunchedFromPackage(IBinder activityToken) {
16575        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16576        if (srec == null) {
16577            return null;
16578        }
16579        return srec.launchedFromPackage;
16580    }
16581
16582    // =========================================================
16583    // LIFETIME MANAGEMENT
16584    // =========================================================
16585
16586    // Returns which broadcast queue the app is the current [or imminent] receiver
16587    // on, or 'null' if the app is not an active broadcast recipient.
16588    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16589        BroadcastRecord r = app.curReceiver;
16590        if (r != null) {
16591            return r.queue;
16592        }
16593
16594        // It's not the current receiver, but it might be starting up to become one
16595        synchronized (this) {
16596            for (BroadcastQueue queue : mBroadcastQueues) {
16597                r = queue.mPendingBroadcast;
16598                if (r != null && r.curApp == app) {
16599                    // found it; report which queue it's in
16600                    return queue;
16601                }
16602            }
16603        }
16604
16605        return null;
16606    }
16607
16608    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16609            boolean doingAll, long now) {
16610        if (mAdjSeq == app.adjSeq) {
16611            // This adjustment has already been computed.
16612            return app.curRawAdj;
16613        }
16614
16615        if (app.thread == null) {
16616            app.adjSeq = mAdjSeq;
16617            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16618            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16619            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16620        }
16621
16622        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16623        app.adjSource = null;
16624        app.adjTarget = null;
16625        app.empty = false;
16626        app.cached = false;
16627
16628        final int activitiesSize = app.activities.size();
16629
16630        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16631            // The max adjustment doesn't allow this app to be anything
16632            // below foreground, so it is not worth doing work for it.
16633            app.adjType = "fixed";
16634            app.adjSeq = mAdjSeq;
16635            app.curRawAdj = app.maxAdj;
16636            app.foregroundActivities = false;
16637            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16638            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16639            // System processes can do UI, and when they do we want to have
16640            // them trim their memory after the user leaves the UI.  To
16641            // facilitate this, here we need to determine whether or not it
16642            // is currently showing UI.
16643            app.systemNoUi = true;
16644            if (app == TOP_APP) {
16645                app.systemNoUi = false;
16646            } else if (activitiesSize > 0) {
16647                for (int j = 0; j < activitiesSize; j++) {
16648                    final ActivityRecord r = app.activities.get(j);
16649                    if (r.visible) {
16650                        app.systemNoUi = false;
16651                    }
16652                }
16653            }
16654            if (!app.systemNoUi) {
16655                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16656            }
16657            return (app.curAdj=app.maxAdj);
16658        }
16659
16660        app.systemNoUi = false;
16661
16662        // Determine the importance of the process, starting with most
16663        // important to least, and assign an appropriate OOM adjustment.
16664        int adj;
16665        int schedGroup;
16666        int procState;
16667        boolean foregroundActivities = false;
16668        BroadcastQueue queue;
16669        if (app == TOP_APP) {
16670            // The last app on the list is the foreground app.
16671            adj = ProcessList.FOREGROUND_APP_ADJ;
16672            schedGroup = Process.THREAD_GROUP_DEFAULT;
16673            app.adjType = "top-activity";
16674            foregroundActivities = true;
16675            procState = ActivityManager.PROCESS_STATE_TOP;
16676        } else if (app.instrumentationClass != null) {
16677            // Don't want to kill running instrumentation.
16678            adj = ProcessList.FOREGROUND_APP_ADJ;
16679            schedGroup = Process.THREAD_GROUP_DEFAULT;
16680            app.adjType = "instrumentation";
16681            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16682        } else if ((queue = isReceivingBroadcast(app)) != null) {
16683            // An app that is currently receiving a broadcast also
16684            // counts as being in the foreground for OOM killer purposes.
16685            // It's placed in a sched group based on the nature of the
16686            // broadcast as reflected by which queue it's active in.
16687            adj = ProcessList.FOREGROUND_APP_ADJ;
16688            schedGroup = (queue == mFgBroadcastQueue)
16689                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16690            app.adjType = "broadcast";
16691            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16692        } else if (app.executingServices.size() > 0) {
16693            // An app that is currently executing a service callback also
16694            // counts as being in the foreground.
16695            adj = ProcessList.FOREGROUND_APP_ADJ;
16696            schedGroup = app.execServicesFg ?
16697                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16698            app.adjType = "exec-service";
16699            procState = ActivityManager.PROCESS_STATE_SERVICE;
16700            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16701        } else {
16702            // As far as we know the process is empty.  We may change our mind later.
16703            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16704            // At this point we don't actually know the adjustment.  Use the cached adj
16705            // value that the caller wants us to.
16706            adj = cachedAdj;
16707            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16708            app.cached = true;
16709            app.empty = true;
16710            app.adjType = "cch-empty";
16711        }
16712
16713        // Examine all activities if not already foreground.
16714        if (!foregroundActivities && activitiesSize > 0) {
16715            for (int j = 0; j < activitiesSize; j++) {
16716                final ActivityRecord r = app.activities.get(j);
16717                if (r.app != app) {
16718                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16719                            + app + "?!?");
16720                    continue;
16721                }
16722                if (r.visible) {
16723                    // App has a visible activity; only upgrade adjustment.
16724                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16725                        adj = ProcessList.VISIBLE_APP_ADJ;
16726                        app.adjType = "visible";
16727                    }
16728                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16729                        procState = ActivityManager.PROCESS_STATE_TOP;
16730                    }
16731                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16732                    app.cached = false;
16733                    app.empty = false;
16734                    foregroundActivities = true;
16735                    break;
16736                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16737                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16738                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16739                        app.adjType = "pausing";
16740                    }
16741                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16742                        procState = ActivityManager.PROCESS_STATE_TOP;
16743                    }
16744                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16745                    app.cached = false;
16746                    app.empty = false;
16747                    foregroundActivities = true;
16748                } else if (r.state == ActivityState.STOPPING) {
16749                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16750                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16751                        app.adjType = "stopping";
16752                    }
16753                    // For the process state, we will at this point consider the
16754                    // process to be cached.  It will be cached either as an activity
16755                    // or empty depending on whether the activity is finishing.  We do
16756                    // this so that we can treat the process as cached for purposes of
16757                    // memory trimming (determing current memory level, trim command to
16758                    // send to process) since there can be an arbitrary number of stopping
16759                    // processes and they should soon all go into the cached state.
16760                    if (!r.finishing) {
16761                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16762                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16763                        }
16764                    }
16765                    app.cached = false;
16766                    app.empty = false;
16767                    foregroundActivities = true;
16768                } else {
16769                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16770                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16771                        app.adjType = "cch-act";
16772                    }
16773                }
16774            }
16775        }
16776
16777        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16778            if (app.foregroundServices) {
16779                // The user is aware of this app, so make it visible.
16780                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16781                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16782                app.cached = false;
16783                app.adjType = "fg-service";
16784                schedGroup = Process.THREAD_GROUP_DEFAULT;
16785            } else if (app.forcingToForeground != null) {
16786                // The user is aware of this app, so make it visible.
16787                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16788                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16789                app.cached = false;
16790                app.adjType = "force-fg";
16791                app.adjSource = app.forcingToForeground;
16792                schedGroup = Process.THREAD_GROUP_DEFAULT;
16793            }
16794        }
16795
16796        if (app == mHeavyWeightProcess) {
16797            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16798                // We don't want to kill the current heavy-weight process.
16799                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16800                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16801                app.cached = false;
16802                app.adjType = "heavy";
16803            }
16804            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16805                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16806            }
16807        }
16808
16809        if (app == mHomeProcess) {
16810            if (adj > ProcessList.HOME_APP_ADJ) {
16811                // This process is hosting what we currently consider to be the
16812                // home app, so we don't want to let it go into the background.
16813                adj = ProcessList.HOME_APP_ADJ;
16814                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16815                app.cached = false;
16816                app.adjType = "home";
16817            }
16818            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16819                procState = ActivityManager.PROCESS_STATE_HOME;
16820            }
16821        }
16822
16823        if (app == mPreviousProcess && app.activities.size() > 0) {
16824            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16825                // This was the previous process that showed UI to the user.
16826                // We want to try to keep it around more aggressively, to give
16827                // a good experience around switching between two apps.
16828                adj = ProcessList.PREVIOUS_APP_ADJ;
16829                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16830                app.cached = false;
16831                app.adjType = "previous";
16832            }
16833            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16834                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16835            }
16836        }
16837
16838        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16839                + " reason=" + app.adjType);
16840
16841        // By default, we use the computed adjustment.  It may be changed if
16842        // there are applications dependent on our services or providers, but
16843        // this gives us a baseline and makes sure we don't get into an
16844        // infinite recursion.
16845        app.adjSeq = mAdjSeq;
16846        app.curRawAdj = adj;
16847        app.hasStartedServices = false;
16848
16849        if (mBackupTarget != null && app == mBackupTarget.app) {
16850            // If possible we want to avoid killing apps while they're being backed up
16851            if (adj > ProcessList.BACKUP_APP_ADJ) {
16852                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16853                adj = ProcessList.BACKUP_APP_ADJ;
16854                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16855                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16856                }
16857                app.adjType = "backup";
16858                app.cached = false;
16859            }
16860            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16861                procState = ActivityManager.PROCESS_STATE_BACKUP;
16862            }
16863        }
16864
16865        boolean mayBeTop = false;
16866
16867        for (int is = app.services.size()-1;
16868                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16869                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16870                        || procState > ActivityManager.PROCESS_STATE_TOP);
16871                is--) {
16872            ServiceRecord s = app.services.valueAt(is);
16873            if (s.startRequested) {
16874                app.hasStartedServices = true;
16875                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16876                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16877                }
16878                if (app.hasShownUi && app != mHomeProcess) {
16879                    // If this process has shown some UI, let it immediately
16880                    // go to the LRU list because it may be pretty heavy with
16881                    // UI stuff.  We'll tag it with a label just to help
16882                    // debug and understand what is going on.
16883                    if (adj > ProcessList.SERVICE_ADJ) {
16884                        app.adjType = "cch-started-ui-services";
16885                    }
16886                } else {
16887                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16888                        // This service has seen some activity within
16889                        // recent memory, so we will keep its process ahead
16890                        // of the background processes.
16891                        if (adj > ProcessList.SERVICE_ADJ) {
16892                            adj = ProcessList.SERVICE_ADJ;
16893                            app.adjType = "started-services";
16894                            app.cached = false;
16895                        }
16896                    }
16897                    // If we have let the service slide into the background
16898                    // state, still have some text describing what it is doing
16899                    // even though the service no longer has an impact.
16900                    if (adj > ProcessList.SERVICE_ADJ) {
16901                        app.adjType = "cch-started-services";
16902                    }
16903                }
16904            }
16905            for (int conni = s.connections.size()-1;
16906                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16907                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16908                            || procState > ActivityManager.PROCESS_STATE_TOP);
16909                    conni--) {
16910                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16911                for (int i = 0;
16912                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16913                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16914                                || procState > ActivityManager.PROCESS_STATE_TOP);
16915                        i++) {
16916                    // XXX should compute this based on the max of
16917                    // all connected clients.
16918                    ConnectionRecord cr = clist.get(i);
16919                    if (cr.binding.client == app) {
16920                        // Binding to ourself is not interesting.
16921                        continue;
16922                    }
16923                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16924                        ProcessRecord client = cr.binding.client;
16925                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16926                                TOP_APP, doingAll, now);
16927                        int clientProcState = client.curProcState;
16928                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16929                            // If the other app is cached for any reason, for purposes here
16930                            // we are going to consider it empty.  The specific cached state
16931                            // doesn't propagate except under certain conditions.
16932                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16933                        }
16934                        String adjType = null;
16935                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16936                            // Not doing bind OOM management, so treat
16937                            // this guy more like a started service.
16938                            if (app.hasShownUi && app != mHomeProcess) {
16939                                // If this process has shown some UI, let it immediately
16940                                // go to the LRU list because it may be pretty heavy with
16941                                // UI stuff.  We'll tag it with a label just to help
16942                                // debug and understand what is going on.
16943                                if (adj > clientAdj) {
16944                                    adjType = "cch-bound-ui-services";
16945                                }
16946                                app.cached = false;
16947                                clientAdj = adj;
16948                                clientProcState = procState;
16949                            } else {
16950                                if (now >= (s.lastActivity
16951                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16952                                    // This service has not seen activity within
16953                                    // recent memory, so allow it to drop to the
16954                                    // LRU list if there is no other reason to keep
16955                                    // it around.  We'll also tag it with a label just
16956                                    // to help debug and undertand what is going on.
16957                                    if (adj > clientAdj) {
16958                                        adjType = "cch-bound-services";
16959                                    }
16960                                    clientAdj = adj;
16961                                }
16962                            }
16963                        }
16964                        if (adj > clientAdj) {
16965                            // If this process has recently shown UI, and
16966                            // the process that is binding to it is less
16967                            // important than being visible, then we don't
16968                            // care about the binding as much as we care
16969                            // about letting this process get into the LRU
16970                            // list to be killed and restarted if needed for
16971                            // memory.
16972                            if (app.hasShownUi && app != mHomeProcess
16973                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16974                                adjType = "cch-bound-ui-services";
16975                            } else {
16976                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16977                                        |Context.BIND_IMPORTANT)) != 0) {
16978                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16979                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16980                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16981                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16982                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16983                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16984                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16985                                    adj = clientAdj;
16986                                } else {
16987                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16988                                        adj = ProcessList.VISIBLE_APP_ADJ;
16989                                    }
16990                                }
16991                                if (!client.cached) {
16992                                    app.cached = false;
16993                                }
16994                                adjType = "service";
16995                            }
16996                        }
16997                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16998                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16999                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17000                            }
17001                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17002                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17003                                    // Special handling of clients who are in the top state.
17004                                    // We *may* want to consider this process to be in the
17005                                    // top state as well, but only if there is not another
17006                                    // reason for it to be running.  Being on the top is a
17007                                    // special state, meaning you are specifically running
17008                                    // for the current top app.  If the process is already
17009                                    // running in the background for some other reason, it
17010                                    // is more important to continue considering it to be
17011                                    // in the background state.
17012                                    mayBeTop = true;
17013                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17014                                } else {
17015                                    // Special handling for above-top states (persistent
17016                                    // processes).  These should not bring the current process
17017                                    // into the top state, since they are not on top.  Instead
17018                                    // give them the best state after that.
17019                                    clientProcState =
17020                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17021                                }
17022                            }
17023                        } else {
17024                            if (clientProcState <
17025                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17026                                clientProcState =
17027                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17028                            }
17029                        }
17030                        if (procState > clientProcState) {
17031                            procState = clientProcState;
17032                        }
17033                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17034                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17035                            app.pendingUiClean = true;
17036                        }
17037                        if (adjType != null) {
17038                            app.adjType = adjType;
17039                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17040                                    .REASON_SERVICE_IN_USE;
17041                            app.adjSource = cr.binding.client;
17042                            app.adjSourceProcState = clientProcState;
17043                            app.adjTarget = s.name;
17044                        }
17045                    }
17046                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17047                        app.treatLikeActivity = true;
17048                    }
17049                    final ActivityRecord a = cr.activity;
17050                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17051                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17052                                (a.visible || a.state == ActivityState.RESUMED
17053                                 || a.state == ActivityState.PAUSING)) {
17054                            adj = ProcessList.FOREGROUND_APP_ADJ;
17055                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17056                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17057                            }
17058                            app.cached = false;
17059                            app.adjType = "service";
17060                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17061                                    .REASON_SERVICE_IN_USE;
17062                            app.adjSource = a;
17063                            app.adjSourceProcState = procState;
17064                            app.adjTarget = s.name;
17065                        }
17066                    }
17067                }
17068            }
17069        }
17070
17071        for (int provi = app.pubProviders.size()-1;
17072                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17073                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17074                        || procState > ActivityManager.PROCESS_STATE_TOP);
17075                provi--) {
17076            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17077            for (int i = cpr.connections.size()-1;
17078                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17079                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17080                            || procState > ActivityManager.PROCESS_STATE_TOP);
17081                    i--) {
17082                ContentProviderConnection conn = cpr.connections.get(i);
17083                ProcessRecord client = conn.client;
17084                if (client == app) {
17085                    // Being our own client is not interesting.
17086                    continue;
17087                }
17088                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17089                int clientProcState = client.curProcState;
17090                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17091                    // If the other app is cached for any reason, for purposes here
17092                    // we are going to consider it empty.
17093                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17094                }
17095                if (adj > clientAdj) {
17096                    if (app.hasShownUi && app != mHomeProcess
17097                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17098                        app.adjType = "cch-ui-provider";
17099                    } else {
17100                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17101                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17102                        app.adjType = "provider";
17103                    }
17104                    app.cached &= client.cached;
17105                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17106                            .REASON_PROVIDER_IN_USE;
17107                    app.adjSource = client;
17108                    app.adjSourceProcState = clientProcState;
17109                    app.adjTarget = cpr.name;
17110                }
17111                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17112                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17113                        // Special handling of clients who are in the top state.
17114                        // We *may* want to consider this process to be in the
17115                        // top state as well, but only if there is not another
17116                        // reason for it to be running.  Being on the top is a
17117                        // special state, meaning you are specifically running
17118                        // for the current top app.  If the process is already
17119                        // running in the background for some other reason, it
17120                        // is more important to continue considering it to be
17121                        // in the background state.
17122                        mayBeTop = true;
17123                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17124                    } else {
17125                        // Special handling for above-top states (persistent
17126                        // processes).  These should not bring the current process
17127                        // into the top state, since they are not on top.  Instead
17128                        // give them the best state after that.
17129                        clientProcState =
17130                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17131                    }
17132                }
17133                if (procState > clientProcState) {
17134                    procState = clientProcState;
17135                }
17136                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17137                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17138                }
17139            }
17140            // If the provider has external (non-framework) process
17141            // dependencies, ensure that its adjustment is at least
17142            // FOREGROUND_APP_ADJ.
17143            if (cpr.hasExternalProcessHandles()) {
17144                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17145                    adj = ProcessList.FOREGROUND_APP_ADJ;
17146                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17147                    app.cached = false;
17148                    app.adjType = "provider";
17149                    app.adjTarget = cpr.name;
17150                }
17151                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17152                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17153                }
17154            }
17155        }
17156
17157        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17158            // A client of one of our services or providers is in the top state.  We
17159            // *may* want to be in the top state, but not if we are already running in
17160            // the background for some other reason.  For the decision here, we are going
17161            // to pick out a few specific states that we want to remain in when a client
17162            // is top (states that tend to be longer-term) and otherwise allow it to go
17163            // to the top state.
17164            switch (procState) {
17165                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17166                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17167                case ActivityManager.PROCESS_STATE_SERVICE:
17168                    // These all are longer-term states, so pull them up to the top
17169                    // of the background states, but not all the way to the top state.
17170                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17171                    break;
17172                default:
17173                    // Otherwise, top is a better choice, so take it.
17174                    procState = ActivityManager.PROCESS_STATE_TOP;
17175                    break;
17176            }
17177        }
17178
17179        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17180            if (app.hasClientActivities) {
17181                // This is a cached process, but with client activities.  Mark it so.
17182                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17183                app.adjType = "cch-client-act";
17184            } else if (app.treatLikeActivity) {
17185                // This is a cached process, but somebody wants us to treat it like it has
17186                // an activity, okay!
17187                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17188                app.adjType = "cch-as-act";
17189            }
17190        }
17191
17192        if (adj == ProcessList.SERVICE_ADJ) {
17193            if (doingAll) {
17194                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17195                mNewNumServiceProcs++;
17196                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17197                if (!app.serviceb) {
17198                    // This service isn't far enough down on the LRU list to
17199                    // normally be a B service, but if we are low on RAM and it
17200                    // is large we want to force it down since we would prefer to
17201                    // keep launcher over it.
17202                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17203                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17204                        app.serviceHighRam = true;
17205                        app.serviceb = true;
17206                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17207                    } else {
17208                        mNewNumAServiceProcs++;
17209                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17210                    }
17211                } else {
17212                    app.serviceHighRam = false;
17213                }
17214            }
17215            if (app.serviceb) {
17216                adj = ProcessList.SERVICE_B_ADJ;
17217            }
17218        }
17219
17220        app.curRawAdj = adj;
17221
17222        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17223        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17224        if (adj > app.maxAdj) {
17225            adj = app.maxAdj;
17226            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17227                schedGroup = Process.THREAD_GROUP_DEFAULT;
17228            }
17229        }
17230
17231        // Do final modification to adj.  Everything we do between here and applying
17232        // the final setAdj must be done in this function, because we will also use
17233        // it when computing the final cached adj later.  Note that we don't need to
17234        // worry about this for max adj above, since max adj will always be used to
17235        // keep it out of the cached vaues.
17236        app.curAdj = app.modifyRawOomAdj(adj);
17237        app.curSchedGroup = schedGroup;
17238        app.curProcState = procState;
17239        app.foregroundActivities = foregroundActivities;
17240
17241        return app.curRawAdj;
17242    }
17243
17244    /**
17245     * Schedule PSS collection of a process.
17246     */
17247    void requestPssLocked(ProcessRecord proc, int procState) {
17248        if (mPendingPssProcesses.contains(proc)) {
17249            return;
17250        }
17251        if (mPendingPssProcesses.size() == 0) {
17252            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17253        }
17254        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17255        proc.pssProcState = procState;
17256        mPendingPssProcesses.add(proc);
17257    }
17258
17259    /**
17260     * Schedule PSS collection of all processes.
17261     */
17262    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17263        if (!always) {
17264            if (now < (mLastFullPssTime +
17265                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17266                return;
17267            }
17268        }
17269        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17270        mLastFullPssTime = now;
17271        mFullPssPending = true;
17272        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17273        mPendingPssProcesses.clear();
17274        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17275            ProcessRecord app = mLruProcesses.get(i);
17276            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17277                app.pssProcState = app.setProcState;
17278                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17279                        isSleeping(), now);
17280                mPendingPssProcesses.add(app);
17281            }
17282        }
17283        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17284    }
17285
17286    /**
17287     * Ask a given process to GC right now.
17288     */
17289    final void performAppGcLocked(ProcessRecord app) {
17290        try {
17291            app.lastRequestedGc = SystemClock.uptimeMillis();
17292            if (app.thread != null) {
17293                if (app.reportLowMemory) {
17294                    app.reportLowMemory = false;
17295                    app.thread.scheduleLowMemory();
17296                } else {
17297                    app.thread.processInBackground();
17298                }
17299            }
17300        } catch (Exception e) {
17301            // whatever.
17302        }
17303    }
17304
17305    /**
17306     * Returns true if things are idle enough to perform GCs.
17307     */
17308    private final boolean canGcNowLocked() {
17309        boolean processingBroadcasts = false;
17310        for (BroadcastQueue q : mBroadcastQueues) {
17311            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17312                processingBroadcasts = true;
17313            }
17314        }
17315        return !processingBroadcasts
17316                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17317    }
17318
17319    /**
17320     * Perform GCs on all processes that are waiting for it, but only
17321     * if things are idle.
17322     */
17323    final void performAppGcsLocked() {
17324        final int N = mProcessesToGc.size();
17325        if (N <= 0) {
17326            return;
17327        }
17328        if (canGcNowLocked()) {
17329            while (mProcessesToGc.size() > 0) {
17330                ProcessRecord proc = mProcessesToGc.remove(0);
17331                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17332                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17333                            <= SystemClock.uptimeMillis()) {
17334                        // To avoid spamming the system, we will GC processes one
17335                        // at a time, waiting a few seconds between each.
17336                        performAppGcLocked(proc);
17337                        scheduleAppGcsLocked();
17338                        return;
17339                    } else {
17340                        // It hasn't been long enough since we last GCed this
17341                        // process...  put it in the list to wait for its time.
17342                        addProcessToGcListLocked(proc);
17343                        break;
17344                    }
17345                }
17346            }
17347
17348            scheduleAppGcsLocked();
17349        }
17350    }
17351
17352    /**
17353     * If all looks good, perform GCs on all processes waiting for them.
17354     */
17355    final void performAppGcsIfAppropriateLocked() {
17356        if (canGcNowLocked()) {
17357            performAppGcsLocked();
17358            return;
17359        }
17360        // Still not idle, wait some more.
17361        scheduleAppGcsLocked();
17362    }
17363
17364    /**
17365     * Schedule the execution of all pending app GCs.
17366     */
17367    final void scheduleAppGcsLocked() {
17368        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17369
17370        if (mProcessesToGc.size() > 0) {
17371            // Schedule a GC for the time to the next process.
17372            ProcessRecord proc = mProcessesToGc.get(0);
17373            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17374
17375            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17376            long now = SystemClock.uptimeMillis();
17377            if (when < (now+GC_TIMEOUT)) {
17378                when = now + GC_TIMEOUT;
17379            }
17380            mHandler.sendMessageAtTime(msg, when);
17381        }
17382    }
17383
17384    /**
17385     * Add a process to the array of processes waiting to be GCed.  Keeps the
17386     * list in sorted order by the last GC time.  The process can't already be
17387     * on the list.
17388     */
17389    final void addProcessToGcListLocked(ProcessRecord proc) {
17390        boolean added = false;
17391        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17392            if (mProcessesToGc.get(i).lastRequestedGc <
17393                    proc.lastRequestedGc) {
17394                added = true;
17395                mProcessesToGc.add(i+1, proc);
17396                break;
17397            }
17398        }
17399        if (!added) {
17400            mProcessesToGc.add(0, proc);
17401        }
17402    }
17403
17404    /**
17405     * Set up to ask a process to GC itself.  This will either do it
17406     * immediately, or put it on the list of processes to gc the next
17407     * time things are idle.
17408     */
17409    final void scheduleAppGcLocked(ProcessRecord app) {
17410        long now = SystemClock.uptimeMillis();
17411        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17412            return;
17413        }
17414        if (!mProcessesToGc.contains(app)) {
17415            addProcessToGcListLocked(app);
17416            scheduleAppGcsLocked();
17417        }
17418    }
17419
17420    final void checkExcessivePowerUsageLocked(boolean doKills) {
17421        updateCpuStatsNow();
17422
17423        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17424        boolean doWakeKills = doKills;
17425        boolean doCpuKills = doKills;
17426        if (mLastPowerCheckRealtime == 0) {
17427            doWakeKills = false;
17428        }
17429        if (mLastPowerCheckUptime == 0) {
17430            doCpuKills = false;
17431        }
17432        if (stats.isScreenOn()) {
17433            doWakeKills = false;
17434        }
17435        final long curRealtime = SystemClock.elapsedRealtime();
17436        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17437        final long curUptime = SystemClock.uptimeMillis();
17438        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17439        mLastPowerCheckRealtime = curRealtime;
17440        mLastPowerCheckUptime = curUptime;
17441        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17442            doWakeKills = false;
17443        }
17444        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17445            doCpuKills = false;
17446        }
17447        int i = mLruProcesses.size();
17448        while (i > 0) {
17449            i--;
17450            ProcessRecord app = mLruProcesses.get(i);
17451            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17452                long wtime;
17453                synchronized (stats) {
17454                    wtime = stats.getProcessWakeTime(app.info.uid,
17455                            app.pid, curRealtime);
17456                }
17457                long wtimeUsed = wtime - app.lastWakeTime;
17458                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17459                if (DEBUG_POWER) {
17460                    StringBuilder sb = new StringBuilder(128);
17461                    sb.append("Wake for ");
17462                    app.toShortString(sb);
17463                    sb.append(": over ");
17464                    TimeUtils.formatDuration(realtimeSince, sb);
17465                    sb.append(" used ");
17466                    TimeUtils.formatDuration(wtimeUsed, sb);
17467                    sb.append(" (");
17468                    sb.append((wtimeUsed*100)/realtimeSince);
17469                    sb.append("%)");
17470                    Slog.i(TAG, sb.toString());
17471                    sb.setLength(0);
17472                    sb.append("CPU for ");
17473                    app.toShortString(sb);
17474                    sb.append(": over ");
17475                    TimeUtils.formatDuration(uptimeSince, sb);
17476                    sb.append(" used ");
17477                    TimeUtils.formatDuration(cputimeUsed, sb);
17478                    sb.append(" (");
17479                    sb.append((cputimeUsed*100)/uptimeSince);
17480                    sb.append("%)");
17481                    Slog.i(TAG, sb.toString());
17482                }
17483                // If a process has held a wake lock for more
17484                // than 50% of the time during this period,
17485                // that sounds bad.  Kill!
17486                if (doWakeKills && realtimeSince > 0
17487                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17488                    synchronized (stats) {
17489                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17490                                realtimeSince, wtimeUsed);
17491                    }
17492                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17493                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17494                } else if (doCpuKills && uptimeSince > 0
17495                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17496                    synchronized (stats) {
17497                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17498                                uptimeSince, cputimeUsed);
17499                    }
17500                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17501                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17502                } else {
17503                    app.lastWakeTime = wtime;
17504                    app.lastCpuTime = app.curCpuTime;
17505                }
17506            }
17507        }
17508    }
17509
17510    private final boolean applyOomAdjLocked(ProcessRecord app,
17511            ProcessRecord TOP_APP, boolean doingAll, long now) {
17512        boolean success = true;
17513
17514        if (app.curRawAdj != app.setRawAdj) {
17515            app.setRawAdj = app.curRawAdj;
17516        }
17517
17518        int changes = 0;
17519
17520        if (app.curAdj != app.setAdj) {
17521            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17522            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17523                TAG, "Set " + app.pid + " " + app.processName +
17524                " adj " + app.curAdj + ": " + app.adjType);
17525            app.setAdj = app.curAdj;
17526        }
17527
17528        if (app.setSchedGroup != app.curSchedGroup) {
17529            app.setSchedGroup = app.curSchedGroup;
17530            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17531                    "Setting process group of " + app.processName
17532                    + " to " + app.curSchedGroup);
17533            if (app.waitingToKill != null &&
17534                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17535                app.kill(app.waitingToKill, true);
17536                success = false;
17537            } else {
17538                if (true) {
17539                    long oldId = Binder.clearCallingIdentity();
17540                    try {
17541                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17542                    } catch (Exception e) {
17543                        Slog.w(TAG, "Failed setting process group of " + app.pid
17544                                + " to " + app.curSchedGroup);
17545                        e.printStackTrace();
17546                    } finally {
17547                        Binder.restoreCallingIdentity(oldId);
17548                    }
17549                } else {
17550                    if (app.thread != null) {
17551                        try {
17552                            app.thread.setSchedulingGroup(app.curSchedGroup);
17553                        } catch (RemoteException e) {
17554                        }
17555                    }
17556                }
17557                Process.setSwappiness(app.pid,
17558                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17559            }
17560        }
17561        if (app.repForegroundActivities != app.foregroundActivities) {
17562            app.repForegroundActivities = app.foregroundActivities;
17563            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17564        }
17565        if (app.repProcState != app.curProcState) {
17566            app.repProcState = app.curProcState;
17567            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17568            if (app.thread != null) {
17569                try {
17570                    if (false) {
17571                        //RuntimeException h = new RuntimeException("here");
17572                        Slog.i(TAG, "Sending new process state " + app.repProcState
17573                                + " to " + app /*, h*/);
17574                    }
17575                    app.thread.setProcessState(app.repProcState);
17576                } catch (RemoteException e) {
17577                }
17578            }
17579        }
17580        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17581                app.setProcState)) {
17582            app.lastStateTime = now;
17583            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17584                    isSleeping(), now);
17585            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17586                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17587                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17588                    + (app.nextPssTime-now) + ": " + app);
17589        } else {
17590            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17591                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17592                requestPssLocked(app, app.setProcState);
17593                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17594                        isSleeping(), now);
17595            } else if (false && DEBUG_PSS) {
17596                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17597            }
17598        }
17599        if (app.setProcState != app.curProcState) {
17600            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17601                    "Proc state change of " + app.processName
17602                    + " to " + app.curProcState);
17603            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17604            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17605            if (setImportant && !curImportant) {
17606                // This app is no longer something we consider important enough to allow to
17607                // use arbitrary amounts of battery power.  Note
17608                // its current wake lock time to later know to kill it if
17609                // it is not behaving well.
17610                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17611                synchronized (stats) {
17612                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17613                            app.pid, SystemClock.elapsedRealtime());
17614                }
17615                app.lastCpuTime = app.curCpuTime;
17616
17617            }
17618            app.setProcState = app.curProcState;
17619            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17620                app.notCachedSinceIdle = false;
17621            }
17622            if (!doingAll) {
17623                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17624            } else {
17625                app.procStateChanged = true;
17626            }
17627        }
17628
17629        if (changes != 0) {
17630            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17631            int i = mPendingProcessChanges.size()-1;
17632            ProcessChangeItem item = null;
17633            while (i >= 0) {
17634                item = mPendingProcessChanges.get(i);
17635                if (item.pid == app.pid) {
17636                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17637                    break;
17638                }
17639                i--;
17640            }
17641            if (i < 0) {
17642                // No existing item in pending changes; need a new one.
17643                final int NA = mAvailProcessChanges.size();
17644                if (NA > 0) {
17645                    item = mAvailProcessChanges.remove(NA-1);
17646                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17647                } else {
17648                    item = new ProcessChangeItem();
17649                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17650                }
17651                item.changes = 0;
17652                item.pid = app.pid;
17653                item.uid = app.info.uid;
17654                if (mPendingProcessChanges.size() == 0) {
17655                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17656                            "*** Enqueueing dispatch processes changed!");
17657                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17658                }
17659                mPendingProcessChanges.add(item);
17660            }
17661            item.changes |= changes;
17662            item.processState = app.repProcState;
17663            item.foregroundActivities = app.repForegroundActivities;
17664            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17665                    + Integer.toHexString(System.identityHashCode(item))
17666                    + " " + app.toShortString() + ": changes=" + item.changes
17667                    + " procState=" + item.processState
17668                    + " foreground=" + item.foregroundActivities
17669                    + " type=" + app.adjType + " source=" + app.adjSource
17670                    + " target=" + app.adjTarget);
17671        }
17672
17673        return success;
17674    }
17675
17676    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17677        if (proc.thread != null) {
17678            if (proc.baseProcessTracker != null) {
17679                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17680            }
17681            if (proc.repProcState >= 0) {
17682                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17683                        proc.repProcState);
17684            }
17685        }
17686    }
17687
17688    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17689            ProcessRecord TOP_APP, boolean doingAll, long now) {
17690        if (app.thread == null) {
17691            return false;
17692        }
17693
17694        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17695
17696        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17697    }
17698
17699    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17700            boolean oomAdj) {
17701        if (isForeground != proc.foregroundServices) {
17702            proc.foregroundServices = isForeground;
17703            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17704                    proc.info.uid);
17705            if (isForeground) {
17706                if (curProcs == null) {
17707                    curProcs = new ArrayList<ProcessRecord>();
17708                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17709                }
17710                if (!curProcs.contains(proc)) {
17711                    curProcs.add(proc);
17712                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17713                            proc.info.packageName, proc.info.uid);
17714                }
17715            } else {
17716                if (curProcs != null) {
17717                    if (curProcs.remove(proc)) {
17718                        mBatteryStatsService.noteEvent(
17719                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17720                                proc.info.packageName, proc.info.uid);
17721                        if (curProcs.size() <= 0) {
17722                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17723                        }
17724                    }
17725                }
17726            }
17727            if (oomAdj) {
17728                updateOomAdjLocked();
17729            }
17730        }
17731    }
17732
17733    private final ActivityRecord resumedAppLocked() {
17734        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17735        String pkg;
17736        int uid;
17737        if (act != null) {
17738            pkg = act.packageName;
17739            uid = act.info.applicationInfo.uid;
17740        } else {
17741            pkg = null;
17742            uid = -1;
17743        }
17744        // Has the UID or resumed package name changed?
17745        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17746                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17747            if (mCurResumedPackage != null) {
17748                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17749                        mCurResumedPackage, mCurResumedUid);
17750            }
17751            mCurResumedPackage = pkg;
17752            mCurResumedUid = uid;
17753            if (mCurResumedPackage != null) {
17754                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17755                        mCurResumedPackage, mCurResumedUid);
17756            }
17757        }
17758        return act;
17759    }
17760
17761    final boolean updateOomAdjLocked(ProcessRecord app) {
17762        final ActivityRecord TOP_ACT = resumedAppLocked();
17763        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17764        final boolean wasCached = app.cached;
17765
17766        mAdjSeq++;
17767
17768        // This is the desired cached adjusment we want to tell it to use.
17769        // If our app is currently cached, we know it, and that is it.  Otherwise,
17770        // we don't know it yet, and it needs to now be cached we will then
17771        // need to do a complete oom adj.
17772        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17773                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17774        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17775                SystemClock.uptimeMillis());
17776        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17777            // Changed to/from cached state, so apps after it in the LRU
17778            // list may also be changed.
17779            updateOomAdjLocked();
17780        }
17781        return success;
17782    }
17783
17784    final void updateOomAdjLocked() {
17785        final ActivityRecord TOP_ACT = resumedAppLocked();
17786        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17787        final long now = SystemClock.uptimeMillis();
17788        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17789        final int N = mLruProcesses.size();
17790
17791        if (false) {
17792            RuntimeException e = new RuntimeException();
17793            e.fillInStackTrace();
17794            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17795        }
17796
17797        mAdjSeq++;
17798        mNewNumServiceProcs = 0;
17799        mNewNumAServiceProcs = 0;
17800
17801        final int emptyProcessLimit;
17802        final int cachedProcessLimit;
17803        if (mProcessLimit <= 0) {
17804            emptyProcessLimit = cachedProcessLimit = 0;
17805        } else if (mProcessLimit == 1) {
17806            emptyProcessLimit = 1;
17807            cachedProcessLimit = 0;
17808        } else {
17809            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17810            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17811        }
17812
17813        // Let's determine how many processes we have running vs.
17814        // how many slots we have for background processes; we may want
17815        // to put multiple processes in a slot of there are enough of
17816        // them.
17817        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17818                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17819        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17820        if (numEmptyProcs > cachedProcessLimit) {
17821            // If there are more empty processes than our limit on cached
17822            // processes, then use the cached process limit for the factor.
17823            // This ensures that the really old empty processes get pushed
17824            // down to the bottom, so if we are running low on memory we will
17825            // have a better chance at keeping around more cached processes
17826            // instead of a gazillion empty processes.
17827            numEmptyProcs = cachedProcessLimit;
17828        }
17829        int emptyFactor = numEmptyProcs/numSlots;
17830        if (emptyFactor < 1) emptyFactor = 1;
17831        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17832        if (cachedFactor < 1) cachedFactor = 1;
17833        int stepCached = 0;
17834        int stepEmpty = 0;
17835        int numCached = 0;
17836        int numEmpty = 0;
17837        int numTrimming = 0;
17838
17839        mNumNonCachedProcs = 0;
17840        mNumCachedHiddenProcs = 0;
17841
17842        // First update the OOM adjustment for each of the
17843        // application processes based on their current state.
17844        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17845        int nextCachedAdj = curCachedAdj+1;
17846        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17847        int nextEmptyAdj = curEmptyAdj+2;
17848        for (int i=N-1; i>=0; i--) {
17849            ProcessRecord app = mLruProcesses.get(i);
17850            if (!app.killedByAm && app.thread != null) {
17851                app.procStateChanged = false;
17852                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17853
17854                // If we haven't yet assigned the final cached adj
17855                // to the process, do that now.
17856                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17857                    switch (app.curProcState) {
17858                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17859                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17860                            // This process is a cached process holding activities...
17861                            // assign it the next cached value for that type, and then
17862                            // step that cached level.
17863                            app.curRawAdj = curCachedAdj;
17864                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17865                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17866                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17867                                    + ")");
17868                            if (curCachedAdj != nextCachedAdj) {
17869                                stepCached++;
17870                                if (stepCached >= cachedFactor) {
17871                                    stepCached = 0;
17872                                    curCachedAdj = nextCachedAdj;
17873                                    nextCachedAdj += 2;
17874                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17875                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17876                                    }
17877                                }
17878                            }
17879                            break;
17880                        default:
17881                            // For everything else, assign next empty cached process
17882                            // level and bump that up.  Note that this means that
17883                            // long-running services that have dropped down to the
17884                            // cached level will be treated as empty (since their process
17885                            // state is still as a service), which is what we want.
17886                            app.curRawAdj = curEmptyAdj;
17887                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17888                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17889                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17890                                    + ")");
17891                            if (curEmptyAdj != nextEmptyAdj) {
17892                                stepEmpty++;
17893                                if (stepEmpty >= emptyFactor) {
17894                                    stepEmpty = 0;
17895                                    curEmptyAdj = nextEmptyAdj;
17896                                    nextEmptyAdj += 2;
17897                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17898                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17899                                    }
17900                                }
17901                            }
17902                            break;
17903                    }
17904                }
17905
17906                applyOomAdjLocked(app, TOP_APP, true, now);
17907
17908                // Count the number of process types.
17909                switch (app.curProcState) {
17910                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17911                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17912                        mNumCachedHiddenProcs++;
17913                        numCached++;
17914                        if (numCached > cachedProcessLimit) {
17915                            app.kill("cached #" + numCached, true);
17916                        }
17917                        break;
17918                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17919                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17920                                && app.lastActivityTime < oldTime) {
17921                            app.kill("empty for "
17922                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17923                                    / 1000) + "s", true);
17924                        } else {
17925                            numEmpty++;
17926                            if (numEmpty > emptyProcessLimit) {
17927                                app.kill("empty #" + numEmpty, true);
17928                            }
17929                        }
17930                        break;
17931                    default:
17932                        mNumNonCachedProcs++;
17933                        break;
17934                }
17935
17936                if (app.isolated && app.services.size() <= 0) {
17937                    // If this is an isolated process, and there are no
17938                    // services running in it, then the process is no longer
17939                    // needed.  We agressively kill these because we can by
17940                    // definition not re-use the same process again, and it is
17941                    // good to avoid having whatever code was running in them
17942                    // left sitting around after no longer needed.
17943                    app.kill("isolated not needed", true);
17944                }
17945
17946                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17947                        && !app.killedByAm) {
17948                    numTrimming++;
17949                }
17950            }
17951        }
17952
17953        mNumServiceProcs = mNewNumServiceProcs;
17954
17955        // Now determine the memory trimming level of background processes.
17956        // Unfortunately we need to start at the back of the list to do this
17957        // properly.  We only do this if the number of background apps we
17958        // are managing to keep around is less than half the maximum we desire;
17959        // if we are keeping a good number around, we'll let them use whatever
17960        // memory they want.
17961        final int numCachedAndEmpty = numCached + numEmpty;
17962        int memFactor;
17963        if (numCached <= ProcessList.TRIM_CACHED_APPS
17964                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17965            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17966                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17967            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17968                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17969            } else {
17970                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17971            }
17972        } else {
17973            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17974        }
17975        // We always allow the memory level to go up (better).  We only allow it to go
17976        // down if we are in a state where that is allowed, *and* the total number of processes
17977        // has gone down since last time.
17978        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17979                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17980                + " last=" + mLastNumProcesses);
17981        if (memFactor > mLastMemoryLevel) {
17982            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17983                memFactor = mLastMemoryLevel;
17984                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17985            }
17986        }
17987        mLastMemoryLevel = memFactor;
17988        mLastNumProcesses = mLruProcesses.size();
17989        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17990        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17991        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17992            if (mLowRamStartTime == 0) {
17993                mLowRamStartTime = now;
17994            }
17995            int step = 0;
17996            int fgTrimLevel;
17997            switch (memFactor) {
17998                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17999                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18000                    break;
18001                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18002                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18003                    break;
18004                default:
18005                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18006                    break;
18007            }
18008            int factor = numTrimming/3;
18009            int minFactor = 2;
18010            if (mHomeProcess != null) minFactor++;
18011            if (mPreviousProcess != null) minFactor++;
18012            if (factor < minFactor) factor = minFactor;
18013            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18014            for (int i=N-1; i>=0; i--) {
18015                ProcessRecord app = mLruProcesses.get(i);
18016                if (allChanged || app.procStateChanged) {
18017                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18018                    app.procStateChanged = false;
18019                }
18020                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18021                        && !app.killedByAm) {
18022                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18023                        try {
18024                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18025                                    "Trimming memory of " + app.processName
18026                                    + " to " + curLevel);
18027                            app.thread.scheduleTrimMemory(curLevel);
18028                        } catch (RemoteException e) {
18029                        }
18030                        if (false) {
18031                            // For now we won't do this; our memory trimming seems
18032                            // to be good enough at this point that destroying
18033                            // activities causes more harm than good.
18034                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18035                                    && app != mHomeProcess && app != mPreviousProcess) {
18036                                // Need to do this on its own message because the stack may not
18037                                // be in a consistent state at this point.
18038                                // For these apps we will also finish their activities
18039                                // to help them free memory.
18040                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18041                            }
18042                        }
18043                    }
18044                    app.trimMemoryLevel = curLevel;
18045                    step++;
18046                    if (step >= factor) {
18047                        step = 0;
18048                        switch (curLevel) {
18049                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18050                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18051                                break;
18052                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18053                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18054                                break;
18055                        }
18056                    }
18057                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18058                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18059                            && app.thread != null) {
18060                        try {
18061                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18062                                    "Trimming memory of heavy-weight " + app.processName
18063                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18064                            app.thread.scheduleTrimMemory(
18065                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18066                        } catch (RemoteException e) {
18067                        }
18068                    }
18069                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18070                } else {
18071                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18072                            || app.systemNoUi) && app.pendingUiClean) {
18073                        // If this application is now in the background and it
18074                        // had done UI, then give it the special trim level to
18075                        // have it free UI resources.
18076                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18077                        if (app.trimMemoryLevel < level && app.thread != null) {
18078                            try {
18079                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18080                                        "Trimming memory of bg-ui " + app.processName
18081                                        + " to " + level);
18082                                app.thread.scheduleTrimMemory(level);
18083                            } catch (RemoteException e) {
18084                            }
18085                        }
18086                        app.pendingUiClean = false;
18087                    }
18088                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18089                        try {
18090                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18091                                    "Trimming memory of fg " + app.processName
18092                                    + " to " + fgTrimLevel);
18093                            app.thread.scheduleTrimMemory(fgTrimLevel);
18094                        } catch (RemoteException e) {
18095                        }
18096                    }
18097                    app.trimMemoryLevel = fgTrimLevel;
18098                }
18099            }
18100        } else {
18101            if (mLowRamStartTime != 0) {
18102                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18103                mLowRamStartTime = 0;
18104            }
18105            for (int i=N-1; i>=0; i--) {
18106                ProcessRecord app = mLruProcesses.get(i);
18107                if (allChanged || app.procStateChanged) {
18108                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18109                    app.procStateChanged = false;
18110                }
18111                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18112                        || app.systemNoUi) && app.pendingUiClean) {
18113                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18114                            && app.thread != null) {
18115                        try {
18116                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18117                                    "Trimming memory of ui hidden " + app.processName
18118                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18119                            app.thread.scheduleTrimMemory(
18120                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18121                        } catch (RemoteException e) {
18122                        }
18123                    }
18124                    app.pendingUiClean = false;
18125                }
18126                app.trimMemoryLevel = 0;
18127            }
18128        }
18129
18130        if (mAlwaysFinishActivities) {
18131            // Need to do this on its own message because the stack may not
18132            // be in a consistent state at this point.
18133            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18134        }
18135
18136        if (allChanged) {
18137            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18138        }
18139
18140        if (mProcessStats.shouldWriteNowLocked(now)) {
18141            mHandler.post(new Runnable() {
18142                @Override public void run() {
18143                    synchronized (ActivityManagerService.this) {
18144                        mProcessStats.writeStateAsyncLocked();
18145                    }
18146                }
18147            });
18148        }
18149
18150        if (DEBUG_OOM_ADJ) {
18151            if (false) {
18152                RuntimeException here = new RuntimeException("here");
18153                here.fillInStackTrace();
18154                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18155            } else {
18156                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18157            }
18158        }
18159    }
18160
18161    final void trimApplications() {
18162        synchronized (this) {
18163            int i;
18164
18165            // First remove any unused application processes whose package
18166            // has been removed.
18167            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18168                final ProcessRecord app = mRemovedProcesses.get(i);
18169                if (app.activities.size() == 0
18170                        && app.curReceiver == null && app.services.size() == 0) {
18171                    Slog.i(
18172                        TAG, "Exiting empty application process "
18173                        + app.processName + " ("
18174                        + (app.thread != null ? app.thread.asBinder() : null)
18175                        + ")\n");
18176                    if (app.pid > 0 && app.pid != MY_PID) {
18177                        app.kill("empty", false);
18178                    } else {
18179                        try {
18180                            app.thread.scheduleExit();
18181                        } catch (Exception e) {
18182                            // Ignore exceptions.
18183                        }
18184                    }
18185                    cleanUpApplicationRecordLocked(app, false, true, -1);
18186                    mRemovedProcesses.remove(i);
18187
18188                    if (app.persistent) {
18189                        addAppLocked(app.info, false, null /* ABI override */);
18190                    }
18191                }
18192            }
18193
18194            // Now update the oom adj for all processes.
18195            updateOomAdjLocked();
18196        }
18197    }
18198
18199    /** This method sends the specified signal to each of the persistent apps */
18200    public void signalPersistentProcesses(int sig) throws RemoteException {
18201        if (sig != Process.SIGNAL_USR1) {
18202            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18203        }
18204
18205        synchronized (this) {
18206            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18207                    != PackageManager.PERMISSION_GRANTED) {
18208                throw new SecurityException("Requires permission "
18209                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18210            }
18211
18212            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18213                ProcessRecord r = mLruProcesses.get(i);
18214                if (r.thread != null && r.persistent) {
18215                    Process.sendSignal(r.pid, sig);
18216                }
18217            }
18218        }
18219    }
18220
18221    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18222        if (proc == null || proc == mProfileProc) {
18223            proc = mProfileProc;
18224            profileType = mProfileType;
18225            clearProfilerLocked();
18226        }
18227        if (proc == null) {
18228            return;
18229        }
18230        try {
18231            proc.thread.profilerControl(false, null, profileType);
18232        } catch (RemoteException e) {
18233            throw new IllegalStateException("Process disappeared");
18234        }
18235    }
18236
18237    private void clearProfilerLocked() {
18238        if (mProfileFd != null) {
18239            try {
18240                mProfileFd.close();
18241            } catch (IOException e) {
18242            }
18243        }
18244        mProfileApp = null;
18245        mProfileProc = null;
18246        mProfileFile = null;
18247        mProfileType = 0;
18248        mAutoStopProfiler = false;
18249        mSamplingInterval = 0;
18250    }
18251
18252    public boolean profileControl(String process, int userId, boolean start,
18253            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18254
18255        try {
18256            synchronized (this) {
18257                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18258                // its own permission.
18259                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18260                        != PackageManager.PERMISSION_GRANTED) {
18261                    throw new SecurityException("Requires permission "
18262                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18263                }
18264
18265                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18266                    throw new IllegalArgumentException("null profile info or fd");
18267                }
18268
18269                ProcessRecord proc = null;
18270                if (process != null) {
18271                    proc = findProcessLocked(process, userId, "profileControl");
18272                }
18273
18274                if (start && (proc == null || proc.thread == null)) {
18275                    throw new IllegalArgumentException("Unknown process: " + process);
18276                }
18277
18278                if (start) {
18279                    stopProfilerLocked(null, 0);
18280                    setProfileApp(proc.info, proc.processName, profilerInfo);
18281                    mProfileProc = proc;
18282                    mProfileType = profileType;
18283                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18284                    try {
18285                        fd = fd.dup();
18286                    } catch (IOException e) {
18287                        fd = null;
18288                    }
18289                    profilerInfo.profileFd = fd;
18290                    proc.thread.profilerControl(start, profilerInfo, profileType);
18291                    fd = null;
18292                    mProfileFd = null;
18293                } else {
18294                    stopProfilerLocked(proc, profileType);
18295                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18296                        try {
18297                            profilerInfo.profileFd.close();
18298                        } catch (IOException e) {
18299                        }
18300                    }
18301                }
18302
18303                return true;
18304            }
18305        } catch (RemoteException e) {
18306            throw new IllegalStateException("Process disappeared");
18307        } finally {
18308            if (profilerInfo != null && profilerInfo.profileFd != null) {
18309                try {
18310                    profilerInfo.profileFd.close();
18311                } catch (IOException e) {
18312                }
18313            }
18314        }
18315    }
18316
18317    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18318        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18319                userId, true, ALLOW_FULL_ONLY, callName, null);
18320        ProcessRecord proc = null;
18321        try {
18322            int pid = Integer.parseInt(process);
18323            synchronized (mPidsSelfLocked) {
18324                proc = mPidsSelfLocked.get(pid);
18325            }
18326        } catch (NumberFormatException e) {
18327        }
18328
18329        if (proc == null) {
18330            ArrayMap<String, SparseArray<ProcessRecord>> all
18331                    = mProcessNames.getMap();
18332            SparseArray<ProcessRecord> procs = all.get(process);
18333            if (procs != null && procs.size() > 0) {
18334                proc = procs.valueAt(0);
18335                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18336                    for (int i=1; i<procs.size(); i++) {
18337                        ProcessRecord thisProc = procs.valueAt(i);
18338                        if (thisProc.userId == userId) {
18339                            proc = thisProc;
18340                            break;
18341                        }
18342                    }
18343                }
18344            }
18345        }
18346
18347        return proc;
18348    }
18349
18350    public boolean dumpHeap(String process, int userId, boolean managed,
18351            String path, ParcelFileDescriptor fd) throws RemoteException {
18352
18353        try {
18354            synchronized (this) {
18355                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18356                // its own permission (same as profileControl).
18357                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18358                        != PackageManager.PERMISSION_GRANTED) {
18359                    throw new SecurityException("Requires permission "
18360                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18361                }
18362
18363                if (fd == null) {
18364                    throw new IllegalArgumentException("null fd");
18365                }
18366
18367                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18368                if (proc == null || proc.thread == null) {
18369                    throw new IllegalArgumentException("Unknown process: " + process);
18370                }
18371
18372                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18373                if (!isDebuggable) {
18374                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18375                        throw new SecurityException("Process not debuggable: " + proc);
18376                    }
18377                }
18378
18379                proc.thread.dumpHeap(managed, path, fd);
18380                fd = null;
18381                return true;
18382            }
18383        } catch (RemoteException e) {
18384            throw new IllegalStateException("Process disappeared");
18385        } finally {
18386            if (fd != null) {
18387                try {
18388                    fd.close();
18389                } catch (IOException e) {
18390                }
18391            }
18392        }
18393    }
18394
18395    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18396    public void monitor() {
18397        synchronized (this) { }
18398    }
18399
18400    void onCoreSettingsChange(Bundle settings) {
18401        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18402            ProcessRecord processRecord = mLruProcesses.get(i);
18403            try {
18404                if (processRecord.thread != null) {
18405                    processRecord.thread.setCoreSettings(settings);
18406                }
18407            } catch (RemoteException re) {
18408                /* ignore */
18409            }
18410        }
18411    }
18412
18413    // Multi-user methods
18414
18415    /**
18416     * Start user, if its not already running, but don't bring it to foreground.
18417     */
18418    @Override
18419    public boolean startUserInBackground(final int userId) {
18420        return startUser(userId, /* foreground */ false);
18421    }
18422
18423    /**
18424     * Start user, if its not already running, and bring it to foreground.
18425     */
18426    boolean startUserInForeground(final int userId, Dialog dlg) {
18427        boolean result = startUser(userId, /* foreground */ true);
18428        dlg.dismiss();
18429        return result;
18430    }
18431
18432    /**
18433     * Refreshes the list of users related to the current user when either a
18434     * user switch happens or when a new related user is started in the
18435     * background.
18436     */
18437    private void updateCurrentProfileIdsLocked() {
18438        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18439                mCurrentUserId, false /* enabledOnly */);
18440        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18441        for (int i = 0; i < currentProfileIds.length; i++) {
18442            currentProfileIds[i] = profiles.get(i).id;
18443        }
18444        mCurrentProfileIds = currentProfileIds;
18445
18446        synchronized (mUserProfileGroupIdsSelfLocked) {
18447            mUserProfileGroupIdsSelfLocked.clear();
18448            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18449            for (int i = 0; i < users.size(); i++) {
18450                UserInfo user = users.get(i);
18451                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18452                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18453                }
18454            }
18455        }
18456    }
18457
18458    private Set getProfileIdsLocked(int userId) {
18459        Set userIds = new HashSet<Integer>();
18460        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18461                userId, false /* enabledOnly */);
18462        for (UserInfo user : profiles) {
18463            userIds.add(Integer.valueOf(user.id));
18464        }
18465        return userIds;
18466    }
18467
18468    @Override
18469    public boolean switchUser(final int userId) {
18470        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18471        String userName;
18472        synchronized (this) {
18473            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18474            if (userInfo == null) {
18475                Slog.w(TAG, "No user info for user #" + userId);
18476                return false;
18477            }
18478            if (userInfo.isManagedProfile()) {
18479                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18480                return false;
18481            }
18482            userName = userInfo.name;
18483            mTargetUserId = userId;
18484        }
18485        mHandler.removeMessages(START_USER_SWITCH_MSG);
18486        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18487        return true;
18488    }
18489
18490    private void showUserSwitchDialog(int userId, String userName) {
18491        // The dialog will show and then initiate the user switch by calling startUserInForeground
18492        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18493                true /* above system */);
18494        d.show();
18495    }
18496
18497    private boolean startUser(final int userId, final boolean foreground) {
18498        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18499                != PackageManager.PERMISSION_GRANTED) {
18500            String msg = "Permission Denial: switchUser() from pid="
18501                    + Binder.getCallingPid()
18502                    + ", uid=" + Binder.getCallingUid()
18503                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18504            Slog.w(TAG, msg);
18505            throw new SecurityException(msg);
18506        }
18507
18508        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18509
18510        final long ident = Binder.clearCallingIdentity();
18511        try {
18512            synchronized (this) {
18513                final int oldUserId = mCurrentUserId;
18514                if (oldUserId == userId) {
18515                    return true;
18516                }
18517
18518                mStackSupervisor.setLockTaskModeLocked(null, false);
18519
18520                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18521                if (userInfo == null) {
18522                    Slog.w(TAG, "No user info for user #" + userId);
18523                    return false;
18524                }
18525                if (foreground && userInfo.isManagedProfile()) {
18526                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18527                    return false;
18528                }
18529
18530                if (foreground) {
18531                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18532                            R.anim.screen_user_enter);
18533                }
18534
18535                boolean needStart = false;
18536
18537                // If the user we are switching to is not currently started, then
18538                // we need to start it now.
18539                if (mStartedUsers.get(userId) == null) {
18540                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18541                    updateStartedUserArrayLocked();
18542                    needStart = true;
18543                }
18544
18545                final Integer userIdInt = Integer.valueOf(userId);
18546                mUserLru.remove(userIdInt);
18547                mUserLru.add(userIdInt);
18548
18549                if (foreground) {
18550                    mCurrentUserId = userId;
18551                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18552                    updateCurrentProfileIdsLocked();
18553                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18554                    // Once the internal notion of the active user has switched, we lock the device
18555                    // with the option to show the user switcher on the keyguard.
18556                    mWindowManager.lockNow(null);
18557                } else {
18558                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18559                    updateCurrentProfileIdsLocked();
18560                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18561                    mUserLru.remove(currentUserIdInt);
18562                    mUserLru.add(currentUserIdInt);
18563                }
18564
18565                final UserStartedState uss = mStartedUsers.get(userId);
18566
18567                // Make sure user is in the started state.  If it is currently
18568                // stopping, we need to knock that off.
18569                if (uss.mState == UserStartedState.STATE_STOPPING) {
18570                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18571                    // so we can just fairly silently bring the user back from
18572                    // the almost-dead.
18573                    uss.mState = UserStartedState.STATE_RUNNING;
18574                    updateStartedUserArrayLocked();
18575                    needStart = true;
18576                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18577                    // This means ACTION_SHUTDOWN has been sent, so we will
18578                    // need to treat this as a new boot of the user.
18579                    uss.mState = UserStartedState.STATE_BOOTING;
18580                    updateStartedUserArrayLocked();
18581                    needStart = true;
18582                }
18583
18584                if (uss.mState == UserStartedState.STATE_BOOTING) {
18585                    // Booting up a new user, need to tell system services about it.
18586                    // Note that this is on the same handler as scheduling of broadcasts,
18587                    // which is important because it needs to go first.
18588                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18589                }
18590
18591                if (foreground) {
18592                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18593                            oldUserId));
18594                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18595                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18596                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18597                            oldUserId, userId, uss));
18598                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18599                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18600                }
18601
18602                if (needStart) {
18603                    // Send USER_STARTED broadcast
18604                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18605                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18606                            | Intent.FLAG_RECEIVER_FOREGROUND);
18607                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18608                    broadcastIntentLocked(null, null, intent,
18609                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18610                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18611                }
18612
18613                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18614                    if (userId != UserHandle.USER_OWNER) {
18615                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18616                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18617                        broadcastIntentLocked(null, null, intent, null,
18618                                new IIntentReceiver.Stub() {
18619                                    public void performReceive(Intent intent, int resultCode,
18620                                            String data, Bundle extras, boolean ordered,
18621                                            boolean sticky, int sendingUser) {
18622                                        onUserInitialized(uss, foreground, oldUserId, userId);
18623                                    }
18624                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18625                                true, false, MY_PID, Process.SYSTEM_UID,
18626                                userId);
18627                        uss.initializing = true;
18628                    } else {
18629                        getUserManagerLocked().makeInitialized(userInfo.id);
18630                    }
18631                }
18632
18633                if (foreground) {
18634                    if (!uss.initializing) {
18635                        moveUserToForeground(uss, oldUserId, userId);
18636                    }
18637                } else {
18638                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18639                }
18640
18641                if (needStart) {
18642                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18643                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18644                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18645                    broadcastIntentLocked(null, null, intent,
18646                            null, new IIntentReceiver.Stub() {
18647                                @Override
18648                                public void performReceive(Intent intent, int resultCode, String data,
18649                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18650                                        throws RemoteException {
18651                                }
18652                            }, 0, null, null,
18653                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18654                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18655                }
18656            }
18657        } finally {
18658            Binder.restoreCallingIdentity(ident);
18659        }
18660
18661        return true;
18662    }
18663
18664    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18665        long ident = Binder.clearCallingIdentity();
18666        try {
18667            Intent intent;
18668            if (oldUserId >= 0) {
18669                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18670                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18671                int count = profiles.size();
18672                for (int i = 0; i < count; i++) {
18673                    int profileUserId = profiles.get(i).id;
18674                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18675                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18676                            | Intent.FLAG_RECEIVER_FOREGROUND);
18677                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18678                    broadcastIntentLocked(null, null, intent,
18679                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18680                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18681                }
18682            }
18683            if (newUserId >= 0) {
18684                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18685                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18686                int count = profiles.size();
18687                for (int i = 0; i < count; i++) {
18688                    int profileUserId = profiles.get(i).id;
18689                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18690                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18691                            | Intent.FLAG_RECEIVER_FOREGROUND);
18692                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18693                    broadcastIntentLocked(null, null, intent,
18694                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18695                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18696                }
18697                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18698                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18699                        | Intent.FLAG_RECEIVER_FOREGROUND);
18700                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18701                broadcastIntentLocked(null, null, intent,
18702                        null, null, 0, null, null,
18703                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18704                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18705            }
18706        } finally {
18707            Binder.restoreCallingIdentity(ident);
18708        }
18709    }
18710
18711    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18712            final int newUserId) {
18713        final int N = mUserSwitchObservers.beginBroadcast();
18714        if (N > 0) {
18715            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18716                int mCount = 0;
18717                @Override
18718                public void sendResult(Bundle data) throws RemoteException {
18719                    synchronized (ActivityManagerService.this) {
18720                        if (mCurUserSwitchCallback == this) {
18721                            mCount++;
18722                            if (mCount == N) {
18723                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18724                            }
18725                        }
18726                    }
18727                }
18728            };
18729            synchronized (this) {
18730                uss.switching = true;
18731                mCurUserSwitchCallback = callback;
18732            }
18733            for (int i=0; i<N; i++) {
18734                try {
18735                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18736                            newUserId, callback);
18737                } catch (RemoteException e) {
18738                }
18739            }
18740        } else {
18741            synchronized (this) {
18742                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18743            }
18744        }
18745        mUserSwitchObservers.finishBroadcast();
18746    }
18747
18748    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18749        synchronized (this) {
18750            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18751            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18752        }
18753    }
18754
18755    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18756        mCurUserSwitchCallback = null;
18757        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18758        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18759                oldUserId, newUserId, uss));
18760    }
18761
18762    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18763        synchronized (this) {
18764            if (foreground) {
18765                moveUserToForeground(uss, oldUserId, newUserId);
18766            }
18767        }
18768
18769        completeSwitchAndInitalize(uss, newUserId, true, false);
18770    }
18771
18772    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18773        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18774        if (homeInFront) {
18775            startHomeActivityLocked(newUserId);
18776        } else {
18777            mStackSupervisor.resumeTopActivitiesLocked();
18778        }
18779        EventLogTags.writeAmSwitchUser(newUserId);
18780        getUserManagerLocked().userForeground(newUserId);
18781        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18782    }
18783
18784    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18785        completeSwitchAndInitalize(uss, newUserId, false, true);
18786    }
18787
18788    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18789            boolean clearInitializing, boolean clearSwitching) {
18790        boolean unfrozen = false;
18791        synchronized (this) {
18792            if (clearInitializing) {
18793                uss.initializing = false;
18794                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18795            }
18796            if (clearSwitching) {
18797                uss.switching = false;
18798            }
18799            if (!uss.switching && !uss.initializing) {
18800                mWindowManager.stopFreezingScreen();
18801                unfrozen = true;
18802            }
18803        }
18804        if (unfrozen) {
18805            final int N = mUserSwitchObservers.beginBroadcast();
18806            for (int i=0; i<N; i++) {
18807                try {
18808                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18809                } catch (RemoteException e) {
18810                }
18811            }
18812            mUserSwitchObservers.finishBroadcast();
18813        }
18814    }
18815
18816    void scheduleStartProfilesLocked() {
18817        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18818            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18819                    DateUtils.SECOND_IN_MILLIS);
18820        }
18821    }
18822
18823    void startProfilesLocked() {
18824        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18825        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18826                mCurrentUserId, false /* enabledOnly */);
18827        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18828        for (UserInfo user : profiles) {
18829            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18830                    && user.id != mCurrentUserId) {
18831                toStart.add(user);
18832            }
18833        }
18834        final int n = toStart.size();
18835        int i = 0;
18836        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18837            startUserInBackground(toStart.get(i).id);
18838        }
18839        if (i < n) {
18840            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18841        }
18842    }
18843
18844    void finishUserBoot(UserStartedState uss) {
18845        synchronized (this) {
18846            if (uss.mState == UserStartedState.STATE_BOOTING
18847                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18848                uss.mState = UserStartedState.STATE_RUNNING;
18849                final int userId = uss.mHandle.getIdentifier();
18850                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18851                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18852                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18853                broadcastIntentLocked(null, null, intent,
18854                        null, null, 0, null, null,
18855                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18856                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18857            }
18858        }
18859    }
18860
18861    void finishUserSwitch(UserStartedState uss) {
18862        synchronized (this) {
18863            finishUserBoot(uss);
18864
18865            startProfilesLocked();
18866
18867            int num = mUserLru.size();
18868            int i = 0;
18869            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18870                Integer oldUserId = mUserLru.get(i);
18871                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18872                if (oldUss == null) {
18873                    // Shouldn't happen, but be sane if it does.
18874                    mUserLru.remove(i);
18875                    num--;
18876                    continue;
18877                }
18878                if (oldUss.mState == UserStartedState.STATE_STOPPING
18879                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18880                    // This user is already stopping, doesn't count.
18881                    num--;
18882                    i++;
18883                    continue;
18884                }
18885                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18886                    // Owner and current can't be stopped, but count as running.
18887                    i++;
18888                    continue;
18889                }
18890                // This is a user to be stopped.
18891                stopUserLocked(oldUserId, null);
18892                num--;
18893                i++;
18894            }
18895        }
18896    }
18897
18898    @Override
18899    public int stopUser(final int userId, final IStopUserCallback callback) {
18900        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18901                != PackageManager.PERMISSION_GRANTED) {
18902            String msg = "Permission Denial: switchUser() from pid="
18903                    + Binder.getCallingPid()
18904                    + ", uid=" + Binder.getCallingUid()
18905                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18906            Slog.w(TAG, msg);
18907            throw new SecurityException(msg);
18908        }
18909        if (userId <= 0) {
18910            throw new IllegalArgumentException("Can't stop primary user " + userId);
18911        }
18912        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18913        synchronized (this) {
18914            return stopUserLocked(userId, callback);
18915        }
18916    }
18917
18918    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18919        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18920        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18921            return ActivityManager.USER_OP_IS_CURRENT;
18922        }
18923
18924        final UserStartedState uss = mStartedUsers.get(userId);
18925        if (uss == null) {
18926            // User is not started, nothing to do...  but we do need to
18927            // callback if requested.
18928            if (callback != null) {
18929                mHandler.post(new Runnable() {
18930                    @Override
18931                    public void run() {
18932                        try {
18933                            callback.userStopped(userId);
18934                        } catch (RemoteException e) {
18935                        }
18936                    }
18937                });
18938            }
18939            return ActivityManager.USER_OP_SUCCESS;
18940        }
18941
18942        if (callback != null) {
18943            uss.mStopCallbacks.add(callback);
18944        }
18945
18946        if (uss.mState != UserStartedState.STATE_STOPPING
18947                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18948            uss.mState = UserStartedState.STATE_STOPPING;
18949            updateStartedUserArrayLocked();
18950
18951            long ident = Binder.clearCallingIdentity();
18952            try {
18953                // We are going to broadcast ACTION_USER_STOPPING and then
18954                // once that is done send a final ACTION_SHUTDOWN and then
18955                // stop the user.
18956                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18957                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18958                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18959                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18960                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18961                // This is the result receiver for the final shutdown broadcast.
18962                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18963                    @Override
18964                    public void performReceive(Intent intent, int resultCode, String data,
18965                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18966                        finishUserStop(uss);
18967                    }
18968                };
18969                // This is the result receiver for the initial stopping broadcast.
18970                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18971                    @Override
18972                    public void performReceive(Intent intent, int resultCode, String data,
18973                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18974                        // On to the next.
18975                        synchronized (ActivityManagerService.this) {
18976                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18977                                // Whoops, we are being started back up.  Abort, abort!
18978                                return;
18979                            }
18980                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18981                        }
18982                        mBatteryStatsService.noteEvent(
18983                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18984                                Integer.toString(userId), userId);
18985                        mSystemServiceManager.stopUser(userId);
18986                        broadcastIntentLocked(null, null, shutdownIntent,
18987                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18988                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18989                    }
18990                };
18991                // Kick things off.
18992                broadcastIntentLocked(null, null, stoppingIntent,
18993                        null, stoppingReceiver, 0, null, null,
18994                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18995                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18996            } finally {
18997                Binder.restoreCallingIdentity(ident);
18998            }
18999        }
19000
19001        return ActivityManager.USER_OP_SUCCESS;
19002    }
19003
19004    void finishUserStop(UserStartedState uss) {
19005        final int userId = uss.mHandle.getIdentifier();
19006        boolean stopped;
19007        ArrayList<IStopUserCallback> callbacks;
19008        synchronized (this) {
19009            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19010            if (mStartedUsers.get(userId) != uss) {
19011                stopped = false;
19012            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19013                stopped = false;
19014            } else {
19015                stopped = true;
19016                // User can no longer run.
19017                mStartedUsers.remove(userId);
19018                mUserLru.remove(Integer.valueOf(userId));
19019                updateStartedUserArrayLocked();
19020
19021                // Clean up all state and processes associated with the user.
19022                // Kill all the processes for the user.
19023                forceStopUserLocked(userId, "finish user");
19024            }
19025
19026            // Explicitly remove the old information in mRecentTasks.
19027            removeRecentTasksForUserLocked(userId);
19028        }
19029
19030        for (int i=0; i<callbacks.size(); i++) {
19031            try {
19032                if (stopped) callbacks.get(i).userStopped(userId);
19033                else callbacks.get(i).userStopAborted(userId);
19034            } catch (RemoteException e) {
19035            }
19036        }
19037
19038        if (stopped) {
19039            mSystemServiceManager.cleanupUser(userId);
19040            synchronized (this) {
19041                mStackSupervisor.removeUserLocked(userId);
19042            }
19043        }
19044    }
19045
19046    @Override
19047    public UserInfo getCurrentUser() {
19048        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19049                != PackageManager.PERMISSION_GRANTED) && (
19050                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19051                != PackageManager.PERMISSION_GRANTED)) {
19052            String msg = "Permission Denial: getCurrentUser() from pid="
19053                    + Binder.getCallingPid()
19054                    + ", uid=" + Binder.getCallingUid()
19055                    + " requires " + INTERACT_ACROSS_USERS;
19056            Slog.w(TAG, msg);
19057            throw new SecurityException(msg);
19058        }
19059        synchronized (this) {
19060            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19061            return getUserManagerLocked().getUserInfo(userId);
19062        }
19063    }
19064
19065    int getCurrentUserIdLocked() {
19066        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19067    }
19068
19069    @Override
19070    public boolean isUserRunning(int userId, boolean orStopped) {
19071        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19072                != PackageManager.PERMISSION_GRANTED) {
19073            String msg = "Permission Denial: isUserRunning() from pid="
19074                    + Binder.getCallingPid()
19075                    + ", uid=" + Binder.getCallingUid()
19076                    + " requires " + INTERACT_ACROSS_USERS;
19077            Slog.w(TAG, msg);
19078            throw new SecurityException(msg);
19079        }
19080        synchronized (this) {
19081            return isUserRunningLocked(userId, orStopped);
19082        }
19083    }
19084
19085    boolean isUserRunningLocked(int userId, boolean orStopped) {
19086        UserStartedState state = mStartedUsers.get(userId);
19087        if (state == null) {
19088            return false;
19089        }
19090        if (orStopped) {
19091            return true;
19092        }
19093        return state.mState != UserStartedState.STATE_STOPPING
19094                && state.mState != UserStartedState.STATE_SHUTDOWN;
19095    }
19096
19097    @Override
19098    public int[] getRunningUserIds() {
19099        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19100                != PackageManager.PERMISSION_GRANTED) {
19101            String msg = "Permission Denial: isUserRunning() from pid="
19102                    + Binder.getCallingPid()
19103                    + ", uid=" + Binder.getCallingUid()
19104                    + " requires " + INTERACT_ACROSS_USERS;
19105            Slog.w(TAG, msg);
19106            throw new SecurityException(msg);
19107        }
19108        synchronized (this) {
19109            return mStartedUserArray;
19110        }
19111    }
19112
19113    private void updateStartedUserArrayLocked() {
19114        int num = 0;
19115        for (int i=0; i<mStartedUsers.size();  i++) {
19116            UserStartedState uss = mStartedUsers.valueAt(i);
19117            // This list does not include stopping users.
19118            if (uss.mState != UserStartedState.STATE_STOPPING
19119                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19120                num++;
19121            }
19122        }
19123        mStartedUserArray = new int[num];
19124        num = 0;
19125        for (int i=0; i<mStartedUsers.size();  i++) {
19126            UserStartedState uss = mStartedUsers.valueAt(i);
19127            if (uss.mState != UserStartedState.STATE_STOPPING
19128                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19129                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19130                num++;
19131            }
19132        }
19133    }
19134
19135    @Override
19136    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19137        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19138                != PackageManager.PERMISSION_GRANTED) {
19139            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19140                    + Binder.getCallingPid()
19141                    + ", uid=" + Binder.getCallingUid()
19142                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19143            Slog.w(TAG, msg);
19144            throw new SecurityException(msg);
19145        }
19146
19147        mUserSwitchObservers.register(observer);
19148    }
19149
19150    @Override
19151    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19152        mUserSwitchObservers.unregister(observer);
19153    }
19154
19155    private boolean userExists(int userId) {
19156        if (userId == 0) {
19157            return true;
19158        }
19159        UserManagerService ums = getUserManagerLocked();
19160        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19161    }
19162
19163    int[] getUsersLocked() {
19164        UserManagerService ums = getUserManagerLocked();
19165        return ums != null ? ums.getUserIds() : new int[] { 0 };
19166    }
19167
19168    UserManagerService getUserManagerLocked() {
19169        if (mUserManager == null) {
19170            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19171            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19172        }
19173        return mUserManager;
19174    }
19175
19176    private int applyUserId(int uid, int userId) {
19177        return UserHandle.getUid(userId, uid);
19178    }
19179
19180    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19181        if (info == null) return null;
19182        ApplicationInfo newInfo = new ApplicationInfo(info);
19183        newInfo.uid = applyUserId(info.uid, userId);
19184        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19185                + info.packageName;
19186        return newInfo;
19187    }
19188
19189    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19190        if (aInfo == null
19191                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19192            return aInfo;
19193        }
19194
19195        ActivityInfo info = new ActivityInfo(aInfo);
19196        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19197        return info;
19198    }
19199
19200    private final class LocalService extends ActivityManagerInternal {
19201        @Override
19202        public void goingToSleep() {
19203            ActivityManagerService.this.goingToSleep();
19204        }
19205
19206        @Override
19207        public void wakingUp() {
19208            ActivityManagerService.this.wakingUp();
19209        }
19210
19211        @Override
19212        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19213                String processName, String abiOverride, int uid, Runnable crashHandler) {
19214            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19215                    processName, abiOverride, uid, crashHandler);
19216        }
19217    }
19218
19219    /**
19220     * An implementation of IAppTask, that allows an app to manage its own tasks via
19221     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19222     * only the process that calls getAppTasks() can call the AppTask methods.
19223     */
19224    class AppTaskImpl extends IAppTask.Stub {
19225        private int mTaskId;
19226        private int mCallingUid;
19227
19228        public AppTaskImpl(int taskId, int callingUid) {
19229            mTaskId = taskId;
19230            mCallingUid = callingUid;
19231        }
19232
19233        private void checkCaller() {
19234            if (mCallingUid != Binder.getCallingUid()) {
19235                throw new SecurityException("Caller " + mCallingUid
19236                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19237            }
19238        }
19239
19240        @Override
19241        public void finishAndRemoveTask() {
19242            checkCaller();
19243
19244            synchronized (ActivityManagerService.this) {
19245                long origId = Binder.clearCallingIdentity();
19246                try {
19247                    if (!removeTaskByIdLocked(mTaskId, false)) {
19248                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19249                    }
19250                } finally {
19251                    Binder.restoreCallingIdentity(origId);
19252                }
19253            }
19254        }
19255
19256        @Override
19257        public ActivityManager.RecentTaskInfo getTaskInfo() {
19258            checkCaller();
19259
19260            synchronized (ActivityManagerService.this) {
19261                long origId = Binder.clearCallingIdentity();
19262                try {
19263                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19264                    if (tr == null) {
19265                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19266                    }
19267                    return createRecentTaskInfoFromTaskRecord(tr);
19268                } finally {
19269                    Binder.restoreCallingIdentity(origId);
19270                }
19271            }
19272        }
19273
19274        @Override
19275        public void moveToFront() {
19276            checkCaller();
19277
19278            final TaskRecord tr;
19279            synchronized (ActivityManagerService.this) {
19280                tr = recentTaskForIdLocked(mTaskId);
19281                if (tr == null) {
19282                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19283                }
19284                if (tr.getRootActivity() != null) {
19285                    moveTaskToFrontLocked(tr.taskId, 0, null);
19286                    return;
19287                }
19288            }
19289
19290            startActivityFromRecentsInner(tr.taskId, null);
19291        }
19292
19293        @Override
19294        public int startActivity(IBinder whoThread, String callingPackage,
19295                Intent intent, String resolvedType, Bundle options) {
19296            checkCaller();
19297
19298            int callingUser = UserHandle.getCallingUserId();
19299            TaskRecord tr;
19300            IApplicationThread appThread;
19301            synchronized (ActivityManagerService.this) {
19302                tr = recentTaskForIdLocked(mTaskId);
19303                if (tr == null) {
19304                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19305                }
19306                appThread = ApplicationThreadNative.asInterface(whoThread);
19307                if (appThread == null) {
19308                    throw new IllegalArgumentException("Bad app thread " + appThread);
19309                }
19310            }
19311            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19312                    resolvedType, null, null, null, null, 0, 0, null, null,
19313                    null, options, callingUser, null, tr);
19314        }
19315
19316        @Override
19317        public void setExcludeFromRecents(boolean exclude) {
19318            checkCaller();
19319
19320            synchronized (ActivityManagerService.this) {
19321                long origId = Binder.clearCallingIdentity();
19322                try {
19323                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19324                    if (tr == null) {
19325                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19326                    }
19327                    Intent intent = tr.getBaseIntent();
19328                    if (exclude) {
19329                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19330                    } else {
19331                        intent.setFlags(intent.getFlags()
19332                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19333                    }
19334                } finally {
19335                    Binder.restoreCallingIdentity(origId);
19336                }
19337            }
19338        }
19339    }
19340}
19341