ActivityManagerService.java revision 308fa0548b8be4d8cca7ba55846d6f61b36f1a7d
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.os.storage.IMountService;
52import android.os.storage.StorageManager;
53import android.service.voice.IVoiceInteractionSession;
54import android.util.ArrayMap;
55import android.util.ArraySet;
56import android.util.SparseIntArray;
57
58import com.android.internal.R;
59import com.android.internal.annotations.GuardedBy;
60import com.android.internal.app.IAppOpsService;
61import com.android.internal.app.IVoiceInteractor;
62import com.android.internal.app.ProcessMap;
63import com.android.internal.app.ProcessStats;
64import com.android.internal.os.BackgroundThread;
65import com.android.internal.os.BatteryStatsImpl;
66import com.android.internal.os.ProcessCpuTracker;
67import com.android.internal.os.TransferPipe;
68import com.android.internal.os.Zygote;
69import com.android.internal.util.FastPrintWriter;
70import com.android.internal.util.FastXmlSerializer;
71import com.android.internal.util.MemInfoReader;
72import com.android.internal.util.Preconditions;
73import com.android.server.AppOpsService;
74import com.android.server.AttributeCache;
75import com.android.server.IntentResolver;
76import com.android.server.LocalServices;
77import com.android.server.ServiceThread;
78import com.android.server.SystemService;
79import com.android.server.SystemServiceManager;
80import com.android.server.Watchdog;
81import com.android.server.am.ActivityStack.ActivityState;
82import com.android.server.firewall.IntentFirewall;
83import com.android.server.pm.Installer;
84import com.android.server.pm.UserManagerService;
85import com.android.server.statusbar.StatusBarManagerInternal;
86import com.android.server.wm.AppTransition;
87import com.android.server.wm.WindowManagerService;
88import com.google.android.collect.Lists;
89import com.google.android.collect.Maps;
90
91import libcore.io.IoUtils;
92
93import org.xmlpull.v1.XmlPullParser;
94import org.xmlpull.v1.XmlPullParserException;
95import org.xmlpull.v1.XmlSerializer;
96
97import android.app.Activity;
98import android.app.ActivityManager;
99import android.app.ActivityManager.RunningTaskInfo;
100import android.app.ActivityManager.StackInfo;
101import android.app.ActivityManagerInternal;
102import android.app.ActivityManagerNative;
103import android.app.ActivityOptions;
104import android.app.ActivityThread;
105import android.app.AlertDialog;
106import android.app.AppGlobals;
107import android.app.ApplicationErrorReport;
108import android.app.Dialog;
109import android.app.IActivityController;
110import android.app.IApplicationThread;
111import android.app.IInstrumentationWatcher;
112import android.app.INotificationManager;
113import android.app.IProcessObserver;
114import android.app.IServiceConnection;
115import android.app.IStopUserCallback;
116import android.app.IUiAutomationConnection;
117import android.app.IUserSwitchObserver;
118import android.app.Instrumentation;
119import android.app.Notification;
120import android.app.NotificationManager;
121import android.app.PendingIntent;
122import android.app.backup.IBackupManager;
123import android.content.ActivityNotFoundException;
124import android.content.BroadcastReceiver;
125import android.content.ClipData;
126import android.content.ComponentCallbacks2;
127import android.content.ComponentName;
128import android.content.ContentProvider;
129import android.content.ContentResolver;
130import android.content.Context;
131import android.content.DialogInterface;
132import android.content.IContentProvider;
133import android.content.IIntentReceiver;
134import android.content.IIntentSender;
135import android.content.Intent;
136import android.content.IntentFilter;
137import android.content.IntentSender;
138import android.content.pm.ActivityInfo;
139import android.content.pm.ApplicationInfo;
140import android.content.pm.ConfigurationInfo;
141import android.content.pm.IPackageDataObserver;
142import android.content.pm.IPackageManager;
143import android.content.pm.InstrumentationInfo;
144import android.content.pm.PackageInfo;
145import android.content.pm.PackageManager;
146import android.content.pm.ParceledListSlice;
147import android.content.pm.UserInfo;
148import android.content.pm.PackageManager.NameNotFoundException;
149import android.content.pm.PathPermission;
150import android.content.pm.ProviderInfo;
151import android.content.pm.ResolveInfo;
152import android.content.pm.ServiceInfo;
153import android.content.res.CompatibilityInfo;
154import android.content.res.Configuration;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.Binder;
159import android.os.Build;
160import android.os.Bundle;
161import android.os.Debug;
162import android.os.DropBoxManager;
163import android.os.Environment;
164import android.os.FactoryTest;
165import android.os.FileObserver;
166import android.os.FileUtils;
167import android.os.Handler;
168import android.os.IBinder;
169import android.os.IPermissionController;
170import android.os.IRemoteCallback;
171import android.os.IUserManager;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.PowerManagerInternal;
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            int hashCode = 1;
800            hashCode = 31 * hashCode + sourceUserId;
801            hashCode = 31 * hashCode + uri.hashCode();
802            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
803            return hashCode;
804        }
805
806        @Override
807        public boolean equals(Object o) {
808            if (o instanceof GrantUri) {
809                GrantUri other = (GrantUri) o;
810                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
811                        && prefix == other.prefix;
812            }
813            return false;
814        }
815
816        @Override
817        public String toString() {
818            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
819            if (prefix) result += " [prefix]";
820            return result;
821        }
822
823        public String toSafeString() {
824            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
825            if (prefix) result += " [prefix]";
826            return result;
827        }
828
829        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
830            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
831                    ContentProvider.getUriWithoutUserId(uri), false);
832        }
833    }
834
835    CoreSettingsObserver mCoreSettingsObserver;
836
837    /**
838     * Thread-local storage used to carry caller permissions over through
839     * indirect content-provider access.
840     */
841    private class Identity {
842        public final IBinder token;
843        public final int pid;
844        public final int uid;
845
846        Identity(IBinder _token, int _pid, int _uid) {
847            token = _token;
848            pid = _pid;
849            uid = _uid;
850        }
851    }
852
853    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
854
855    /**
856     * All information we have collected about the runtime performance of
857     * any user id that can impact battery performance.
858     */
859    final BatteryStatsService mBatteryStatsService;
860
861    /**
862     * Information about component usage
863     */
864    UsageStatsManagerInternal mUsageStatsService;
865
866    /**
867     * Information about and control over application operations
868     */
869    final AppOpsService mAppOpsService;
870
871    /**
872     * Save recent tasks information across reboots.
873     */
874    final TaskPersister mTaskPersister;
875
876    /**
877     * Current configuration information.  HistoryRecord objects are given
878     * a reference to this object to indicate which configuration they are
879     * currently running in, so this object must be kept immutable.
880     */
881    Configuration mConfiguration = new Configuration();
882
883    /**
884     * Current sequencing integer of the configuration, for skipping old
885     * configurations.
886     */
887    int mConfigurationSeq = 0;
888
889    /**
890     * Hardware-reported OpenGLES version.
891     */
892    final int GL_ES_VERSION;
893
894    /**
895     * List of initialization arguments to pass to all processes when binding applications to them.
896     * For example, references to the commonly used services.
897     */
898    HashMap<String, IBinder> mAppBindArgs;
899
900    /**
901     * Temporary to avoid allocations.  Protected by main lock.
902     */
903    final StringBuilder mStringBuilder = new StringBuilder(256);
904
905    /**
906     * Used to control how we initialize the service.
907     */
908    ComponentName mTopComponent;
909    String mTopAction = Intent.ACTION_MAIN;
910    String mTopData;
911    boolean mProcessesReady = false;
912    boolean mSystemReady = false;
913    boolean mBooting = false;
914    boolean mCallFinishBooting = false;
915    boolean mBootAnimationComplete = false;
916    boolean mWaitingUpdate = false;
917    boolean mDidUpdate = false;
918    boolean mOnBattery = false;
919    boolean mLaunchWarningShown = false;
920
921    Context mContext;
922
923    int mFactoryTest;
924
925    boolean mCheckedForSetup;
926
927    /**
928     * The time at which we will allow normal application switches again,
929     * after a call to {@link #stopAppSwitches()}.
930     */
931    long mAppSwitchesAllowedTime;
932
933    /**
934     * This is set to true after the first switch after mAppSwitchesAllowedTime
935     * is set; any switches after that will clear the time.
936     */
937    boolean mDidAppSwitch;
938
939    /**
940     * Last time (in realtime) at which we checked for power usage.
941     */
942    long mLastPowerCheckRealtime;
943
944    /**
945     * Last time (in uptime) at which we checked for power usage.
946     */
947    long mLastPowerCheckUptime;
948
949    /**
950     * Set while we are wanting to sleep, to prevent any
951     * activities from being started/resumed.
952     */
953    private boolean mSleeping = false;
954
955    /**
956     * Set while we are running a voice interaction.  This overrides
957     * sleeping while it is active.
958     */
959    private boolean mRunningVoice = false;
960
961    /**
962     * State of external calls telling us if the device is awake or asleep.
963     */
964    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
965
966    static final int LOCK_SCREEN_HIDDEN = 0;
967    static final int LOCK_SCREEN_LEAVING = 1;
968    static final int LOCK_SCREEN_SHOWN = 2;
969    /**
970     * State of external call telling us if the lock screen is shown.
971     */
972    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
973
974    /**
975     * Set if we are shutting down the system, similar to sleeping.
976     */
977    boolean mShuttingDown = false;
978
979    /**
980     * Current sequence id for oom_adj computation traversal.
981     */
982    int mAdjSeq = 0;
983
984    /**
985     * Current sequence id for process LRU updating.
986     */
987    int mLruSeq = 0;
988
989    /**
990     * Keep track of the non-cached/empty process we last found, to help
991     * determine how to distribute cached/empty processes next time.
992     */
993    int mNumNonCachedProcs = 0;
994
995    /**
996     * Keep track of the number of cached hidden procs, to balance oom adj
997     * distribution between those and empty procs.
998     */
999    int mNumCachedHiddenProcs = 0;
1000
1001    /**
1002     * Keep track of the number of service processes we last found, to
1003     * determine on the next iteration which should be B services.
1004     */
1005    int mNumServiceProcs = 0;
1006    int mNewNumAServiceProcs = 0;
1007    int mNewNumServiceProcs = 0;
1008
1009    /**
1010     * Allow the current computed overall memory level of the system to go down?
1011     * This is set to false when we are killing processes for reasons other than
1012     * memory management, so that the now smaller process list will not be taken as
1013     * an indication that memory is tighter.
1014     */
1015    boolean mAllowLowerMemLevel = false;
1016
1017    /**
1018     * The last computed memory level, for holding when we are in a state that
1019     * processes are going away for other reasons.
1020     */
1021    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1022
1023    /**
1024     * The last total number of process we have, to determine if changes actually look
1025     * like a shrinking number of process due to lower RAM.
1026     */
1027    int mLastNumProcesses;
1028
1029    /**
1030     * The uptime of the last time we performed idle maintenance.
1031     */
1032    long mLastIdleTime = SystemClock.uptimeMillis();
1033
1034    /**
1035     * Total time spent with RAM that has been added in the past since the last idle time.
1036     */
1037    long mLowRamTimeSinceLastIdle = 0;
1038
1039    /**
1040     * If RAM is currently low, when that horrible situation started.
1041     */
1042    long mLowRamStartTime = 0;
1043
1044    /**
1045     * For reporting to battery stats the current top application.
1046     */
1047    private String mCurResumedPackage = null;
1048    private int mCurResumedUid = -1;
1049
1050    /**
1051     * For reporting to battery stats the apps currently running foreground
1052     * service.  The ProcessMap is package/uid tuples; each of these contain
1053     * an array of the currently foreground processes.
1054     */
1055    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1056            = new ProcessMap<ArrayList<ProcessRecord>>();
1057
1058    /**
1059     * This is set if we had to do a delayed dexopt of an app before launching
1060     * it, to increase the ANR timeouts in that case.
1061     */
1062    boolean mDidDexOpt;
1063
1064    /**
1065     * Set if the systemServer made a call to enterSafeMode.
1066     */
1067    boolean mSafeMode;
1068
1069    String mDebugApp = null;
1070    boolean mWaitForDebugger = false;
1071    boolean mDebugTransient = false;
1072    String mOrigDebugApp = null;
1073    boolean mOrigWaitForDebugger = false;
1074    boolean mAlwaysFinishActivities = false;
1075    IActivityController mController = null;
1076    String mProfileApp = null;
1077    ProcessRecord mProfileProc = null;
1078    String mProfileFile;
1079    ParcelFileDescriptor mProfileFd;
1080    int mSamplingInterval = 0;
1081    boolean mAutoStopProfiler = false;
1082    int mProfileType = 0;
1083    String mOpenGlTraceApp = null;
1084
1085    static class ProcessChangeItem {
1086        static final int CHANGE_ACTIVITIES = 1<<0;
1087        static final int CHANGE_PROCESS_STATE = 1<<1;
1088        int changes;
1089        int uid;
1090        int pid;
1091        int processState;
1092        boolean foregroundActivities;
1093    }
1094
1095    final RemoteCallbackList<IProcessObserver> mProcessObservers
1096            = new RemoteCallbackList<IProcessObserver>();
1097    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1098
1099    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1100            = new ArrayList<ProcessChangeItem>();
1101    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1102            = new ArrayList<ProcessChangeItem>();
1103
1104    /**
1105     * Runtime CPU use collection thread.  This object's lock is used to
1106     * perform synchronization with the thread (notifying it to run).
1107     */
1108    final Thread mProcessCpuThread;
1109
1110    /**
1111     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1112     * Must acquire this object's lock when accessing it.
1113     * NOTE: this lock will be held while doing long operations (trawling
1114     * through all processes in /proc), so it should never be acquired by
1115     * any critical paths such as when holding the main activity manager lock.
1116     */
1117    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1118            MONITOR_THREAD_CPU_USAGE);
1119    final AtomicLong mLastCpuTime = new AtomicLong(0);
1120    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1121
1122    long mLastWriteTime = 0;
1123
1124    /**
1125     * Used to retain an update lock when the foreground activity is in
1126     * immersive mode.
1127     */
1128    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1129
1130    /**
1131     * Set to true after the system has finished booting.
1132     */
1133    boolean mBooted = false;
1134
1135    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1136    int mProcessLimitOverride = -1;
1137
1138    WindowManagerService mWindowManager;
1139
1140    final ActivityThread mSystemThread;
1141
1142    // Holds the current foreground user's id
1143    int mCurrentUserId = 0;
1144    // Holds the target user's id during a user switch
1145    int mTargetUserId = UserHandle.USER_NULL;
1146    // If there are multiple profiles for the current user, their ids are here
1147    // Currently only the primary user can have managed profiles
1148    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1149
1150    /**
1151     * Mapping from each known user ID to the profile group ID it is associated with.
1152     */
1153    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1154
1155    private UserManagerService mUserManager;
1156
1157    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1158        final ProcessRecord mApp;
1159        final int mPid;
1160        final IApplicationThread mAppThread;
1161
1162        AppDeathRecipient(ProcessRecord app, int pid,
1163                IApplicationThread thread) {
1164            if (localLOGV) Slog.v(
1165                TAG, "New death recipient " + this
1166                + " for thread " + thread.asBinder());
1167            mApp = app;
1168            mPid = pid;
1169            mAppThread = thread;
1170        }
1171
1172        @Override
1173        public void binderDied() {
1174            if (localLOGV) Slog.v(
1175                TAG, "Death received in " + this
1176                + " for thread " + mAppThread.asBinder());
1177            synchronized(ActivityManagerService.this) {
1178                appDiedLocked(mApp, mPid, mAppThread);
1179            }
1180        }
1181    }
1182
1183    static final int SHOW_ERROR_MSG = 1;
1184    static final int SHOW_NOT_RESPONDING_MSG = 2;
1185    static final int SHOW_FACTORY_ERROR_MSG = 3;
1186    static final int UPDATE_CONFIGURATION_MSG = 4;
1187    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1188    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1189    static final int SERVICE_TIMEOUT_MSG = 12;
1190    static final int UPDATE_TIME_ZONE = 13;
1191    static final int SHOW_UID_ERROR_MSG = 14;
1192    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1193    static final int PROC_START_TIMEOUT_MSG = 20;
1194    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1195    static final int KILL_APPLICATION_MSG = 22;
1196    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1197    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1198    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1199    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1200    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1201    static final int CLEAR_DNS_CACHE_MSG = 28;
1202    static final int UPDATE_HTTP_PROXY_MSG = 29;
1203    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1204    static final int DISPATCH_PROCESSES_CHANGED = 31;
1205    static final int DISPATCH_PROCESS_DIED = 32;
1206    static final int REPORT_MEM_USAGE_MSG = 33;
1207    static final int REPORT_USER_SWITCH_MSG = 34;
1208    static final int CONTINUE_USER_SWITCH_MSG = 35;
1209    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1210    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1211    static final int PERSIST_URI_GRANTS_MSG = 38;
1212    static final int REQUEST_ALL_PSS_MSG = 39;
1213    static final int START_PROFILES_MSG = 40;
1214    static final int UPDATE_TIME = 41;
1215    static final int SYSTEM_USER_START_MSG = 42;
1216    static final int SYSTEM_USER_CURRENT_MSG = 43;
1217    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1218    static final int FINISH_BOOTING_MSG = 45;
1219    static final int START_USER_SWITCH_MSG = 46;
1220    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1221    static final int DISMISS_DIALOG_MSG = 48;
1222
1223    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1224    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1225    static final int FIRST_COMPAT_MODE_MSG = 300;
1226    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1227
1228    CompatModeDialog mCompatModeDialog;
1229    long mLastMemUsageReportTime = 0;
1230
1231    /**
1232     * Flag whether the current user is a "monkey", i.e. whether
1233     * the UI is driven by a UI automation tool.
1234     */
1235    private boolean mUserIsMonkey;
1236
1237    /** Flag whether the device has a Recents UI */
1238    boolean mHasRecents;
1239
1240    /** The dimensions of the thumbnails in the Recents UI. */
1241    int mThumbnailWidth;
1242    int mThumbnailHeight;
1243
1244    final ServiceThread mHandlerThread;
1245    final MainHandler mHandler;
1246
1247    final class MainHandler extends Handler {
1248        public MainHandler(Looper looper) {
1249            super(looper, null, true);
1250        }
1251
1252        @Override
1253        public void handleMessage(Message msg) {
1254            switch (msg.what) {
1255            case SHOW_ERROR_MSG: {
1256                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1257                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1258                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1259                synchronized (ActivityManagerService.this) {
1260                    ProcessRecord proc = (ProcessRecord)data.get("app");
1261                    AppErrorResult res = (AppErrorResult) data.get("result");
1262                    if (proc != null && proc.crashDialog != null) {
1263                        Slog.e(TAG, "App already has crash dialog: " + proc);
1264                        if (res != null) {
1265                            res.set(0);
1266                        }
1267                        return;
1268                    }
1269                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1270                            >= Process.FIRST_APPLICATION_UID
1271                            && proc.pid != MY_PID);
1272                    for (int userId : mCurrentProfileIds) {
1273                        isBackground &= (proc.userId != userId);
1274                    }
1275                    if (isBackground && !showBackground) {
1276                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1277                        if (res != null) {
1278                            res.set(0);
1279                        }
1280                        return;
1281                    }
1282                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1283                        Dialog d = new AppErrorDialog(mContext,
1284                                ActivityManagerService.this, res, proc);
1285                        d.show();
1286                        proc.crashDialog = d;
1287                    } else {
1288                        // The device is asleep, so just pretend that the user
1289                        // saw a crash dialog and hit "force quit".
1290                        if (res != null) {
1291                            res.set(0);
1292                        }
1293                    }
1294                }
1295
1296                ensureBootCompleted();
1297            } break;
1298            case SHOW_NOT_RESPONDING_MSG: {
1299                synchronized (ActivityManagerService.this) {
1300                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1301                    ProcessRecord proc = (ProcessRecord)data.get("app");
1302                    if (proc != null && proc.anrDialog != null) {
1303                        Slog.e(TAG, "App already has anr dialog: " + proc);
1304                        return;
1305                    }
1306
1307                    Intent intent = new Intent("android.intent.action.ANR");
1308                    if (!mProcessesReady) {
1309                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1310                                | Intent.FLAG_RECEIVER_FOREGROUND);
1311                    }
1312                    broadcastIntentLocked(null, null, intent,
1313                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1314                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1315
1316                    if (mShowDialogs) {
1317                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1318                                mContext, proc, (ActivityRecord)data.get("activity"),
1319                                msg.arg1 != 0);
1320                        d.show();
1321                        proc.anrDialog = d;
1322                    } else {
1323                        // Just kill the app if there is no dialog to be shown.
1324                        killAppAtUsersRequest(proc, null);
1325                    }
1326                }
1327
1328                ensureBootCompleted();
1329            } break;
1330            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1331                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1332                synchronized (ActivityManagerService.this) {
1333                    ProcessRecord proc = (ProcessRecord) data.get("app");
1334                    if (proc == null) {
1335                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1336                        break;
1337                    }
1338                    if (proc.crashDialog != null) {
1339                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1340                        return;
1341                    }
1342                    AppErrorResult res = (AppErrorResult) data.get("result");
1343                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1344                        Dialog d = new StrictModeViolationDialog(mContext,
1345                                ActivityManagerService.this, res, proc);
1346                        d.show();
1347                        proc.crashDialog = d;
1348                    } else {
1349                        // The device is asleep, so just pretend that the user
1350                        // saw a crash dialog and hit "force quit".
1351                        res.set(0);
1352                    }
1353                }
1354                ensureBootCompleted();
1355            } break;
1356            case SHOW_FACTORY_ERROR_MSG: {
1357                Dialog d = new FactoryErrorDialog(
1358                    mContext, msg.getData().getCharSequence("msg"));
1359                d.show();
1360                ensureBootCompleted();
1361            } break;
1362            case UPDATE_CONFIGURATION_MSG: {
1363                final ContentResolver resolver = mContext.getContentResolver();
1364                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1365            } break;
1366            case GC_BACKGROUND_PROCESSES_MSG: {
1367                synchronized (ActivityManagerService.this) {
1368                    performAppGcsIfAppropriateLocked();
1369                }
1370            } break;
1371            case WAIT_FOR_DEBUGGER_MSG: {
1372                synchronized (ActivityManagerService.this) {
1373                    ProcessRecord app = (ProcessRecord)msg.obj;
1374                    if (msg.arg1 != 0) {
1375                        if (!app.waitedForDebugger) {
1376                            Dialog d = new AppWaitingForDebuggerDialog(
1377                                    ActivityManagerService.this,
1378                                    mContext, app);
1379                            app.waitDialog = d;
1380                            app.waitedForDebugger = true;
1381                            d.show();
1382                        }
1383                    } else {
1384                        if (app.waitDialog != null) {
1385                            app.waitDialog.dismiss();
1386                            app.waitDialog = null;
1387                        }
1388                    }
1389                }
1390            } break;
1391            case SERVICE_TIMEOUT_MSG: {
1392                if (mDidDexOpt) {
1393                    mDidDexOpt = false;
1394                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1395                    nmsg.obj = msg.obj;
1396                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1397                    return;
1398                }
1399                mServices.serviceTimeout((ProcessRecord)msg.obj);
1400            } break;
1401            case UPDATE_TIME_ZONE: {
1402                synchronized (ActivityManagerService.this) {
1403                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1404                        ProcessRecord r = mLruProcesses.get(i);
1405                        if (r.thread != null) {
1406                            try {
1407                                r.thread.updateTimeZone();
1408                            } catch (RemoteException ex) {
1409                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1410                            }
1411                        }
1412                    }
1413                }
1414            } break;
1415            case CLEAR_DNS_CACHE_MSG: {
1416                synchronized (ActivityManagerService.this) {
1417                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1418                        ProcessRecord r = mLruProcesses.get(i);
1419                        if (r.thread != null) {
1420                            try {
1421                                r.thread.clearDnsCache();
1422                            } catch (RemoteException ex) {
1423                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1424                            }
1425                        }
1426                    }
1427                }
1428            } break;
1429            case UPDATE_HTTP_PROXY_MSG: {
1430                ProxyInfo proxy = (ProxyInfo)msg.obj;
1431                String host = "";
1432                String port = "";
1433                String exclList = "";
1434                Uri pacFileUrl = Uri.EMPTY;
1435                if (proxy != null) {
1436                    host = proxy.getHost();
1437                    port = Integer.toString(proxy.getPort());
1438                    exclList = proxy.getExclusionListAsString();
1439                    pacFileUrl = proxy.getPacFileUrl();
1440                }
1441                synchronized (ActivityManagerService.this) {
1442                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1443                        ProcessRecord r = mLruProcesses.get(i);
1444                        if (r.thread != null) {
1445                            try {
1446                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1447                            } catch (RemoteException ex) {
1448                                Slog.w(TAG, "Failed to update http proxy for: " +
1449                                        r.info.processName);
1450                            }
1451                        }
1452                    }
1453                }
1454            } break;
1455            case SHOW_UID_ERROR_MSG: {
1456                if (mShowDialogs) {
1457                    AlertDialog d = new BaseErrorDialog(mContext);
1458                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1459                    d.setCancelable(false);
1460                    d.setTitle(mContext.getText(R.string.android_system_label));
1461                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1462                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1463                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1464                    d.show();
1465                }
1466            } break;
1467            case SHOW_FINGERPRINT_ERROR_MSG: {
1468                if (mShowDialogs) {
1469                    AlertDialog d = new BaseErrorDialog(mContext);
1470                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1471                    d.setCancelable(false);
1472                    d.setTitle(mContext.getText(R.string.android_system_label));
1473                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1474                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1475                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1476                    d.show();
1477                }
1478            } break;
1479            case PROC_START_TIMEOUT_MSG: {
1480                if (mDidDexOpt) {
1481                    mDidDexOpt = false;
1482                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1483                    nmsg.obj = msg.obj;
1484                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1485                    return;
1486                }
1487                ProcessRecord app = (ProcessRecord)msg.obj;
1488                synchronized (ActivityManagerService.this) {
1489                    processStartTimedOutLocked(app);
1490                }
1491            } break;
1492            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1493                synchronized (ActivityManagerService.this) {
1494                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1495                }
1496            } break;
1497            case KILL_APPLICATION_MSG: {
1498                synchronized (ActivityManagerService.this) {
1499                    int appid = msg.arg1;
1500                    boolean restart = (msg.arg2 == 1);
1501                    Bundle bundle = (Bundle)msg.obj;
1502                    String pkg = bundle.getString("pkg");
1503                    String reason = bundle.getString("reason");
1504                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1505                            false, UserHandle.USER_ALL, reason);
1506                }
1507            } break;
1508            case FINALIZE_PENDING_INTENT_MSG: {
1509                ((PendingIntentRecord)msg.obj).completeFinalize();
1510            } break;
1511            case POST_HEAVY_NOTIFICATION_MSG: {
1512                INotificationManager inm = NotificationManager.getService();
1513                if (inm == null) {
1514                    return;
1515                }
1516
1517                ActivityRecord root = (ActivityRecord)msg.obj;
1518                ProcessRecord process = root.app;
1519                if (process == null) {
1520                    return;
1521                }
1522
1523                try {
1524                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1525                    String text = mContext.getString(R.string.heavy_weight_notification,
1526                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1527                    Notification notification = new Notification();
1528                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1529                    notification.when = 0;
1530                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1531                    notification.tickerText = text;
1532                    notification.defaults = 0; // please be quiet
1533                    notification.sound = null;
1534                    notification.vibrate = null;
1535                    notification.color = mContext.getResources().getColor(
1536                            com.android.internal.R.color.system_notification_accent_color);
1537                    notification.setLatestEventInfo(context, text,
1538                            mContext.getText(R.string.heavy_weight_notification_detail),
1539                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1540                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1541                                    new UserHandle(root.userId)));
1542
1543                    try {
1544                        int[] outId = new int[1];
1545                        inm.enqueueNotificationWithTag("android", "android", null,
1546                                R.string.heavy_weight_notification,
1547                                notification, outId, root.userId);
1548                    } catch (RuntimeException e) {
1549                        Slog.w(ActivityManagerService.TAG,
1550                                "Error showing notification for heavy-weight app", e);
1551                    } catch (RemoteException e) {
1552                    }
1553                } catch (NameNotFoundException e) {
1554                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1555                }
1556            } break;
1557            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1558                INotificationManager inm = NotificationManager.getService();
1559                if (inm == null) {
1560                    return;
1561                }
1562                try {
1563                    inm.cancelNotificationWithTag("android", null,
1564                            R.string.heavy_weight_notification,  msg.arg1);
1565                } catch (RuntimeException e) {
1566                    Slog.w(ActivityManagerService.TAG,
1567                            "Error canceling notification for service", e);
1568                } catch (RemoteException e) {
1569                }
1570            } break;
1571            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1572                synchronized (ActivityManagerService.this) {
1573                    checkExcessivePowerUsageLocked(true);
1574                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1575                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1576                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1577                }
1578            } break;
1579            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1580                synchronized (ActivityManagerService.this) {
1581                    ActivityRecord ar = (ActivityRecord)msg.obj;
1582                    if (mCompatModeDialog != null) {
1583                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1584                                ar.info.applicationInfo.packageName)) {
1585                            return;
1586                        }
1587                        mCompatModeDialog.dismiss();
1588                        mCompatModeDialog = null;
1589                    }
1590                    if (ar != null && false) {
1591                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1592                                ar.packageName)) {
1593                            int mode = mCompatModePackages.computeCompatModeLocked(
1594                                    ar.info.applicationInfo);
1595                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1596                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1597                                mCompatModeDialog = new CompatModeDialog(
1598                                        ActivityManagerService.this, mContext,
1599                                        ar.info.applicationInfo);
1600                                mCompatModeDialog.show();
1601                            }
1602                        }
1603                    }
1604                }
1605                break;
1606            }
1607            case DISPATCH_PROCESSES_CHANGED: {
1608                dispatchProcessesChanged();
1609                break;
1610            }
1611            case DISPATCH_PROCESS_DIED: {
1612                final int pid = msg.arg1;
1613                final int uid = msg.arg2;
1614                dispatchProcessDied(pid, uid);
1615                break;
1616            }
1617            case REPORT_MEM_USAGE_MSG: {
1618                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1619                Thread thread = new Thread() {
1620                    @Override public void run() {
1621                        reportMemUsage(memInfos);
1622                    }
1623                };
1624                thread.start();
1625                break;
1626            }
1627            case START_USER_SWITCH_MSG: {
1628                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1629                break;
1630            }
1631            case REPORT_USER_SWITCH_MSG: {
1632                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1633                break;
1634            }
1635            case CONTINUE_USER_SWITCH_MSG: {
1636                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1637                break;
1638            }
1639            case USER_SWITCH_TIMEOUT_MSG: {
1640                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1641                break;
1642            }
1643            case IMMERSIVE_MODE_LOCK_MSG: {
1644                final boolean nextState = (msg.arg1 != 0);
1645                if (mUpdateLock.isHeld() != nextState) {
1646                    if (DEBUG_IMMERSIVE) {
1647                        final ActivityRecord r = (ActivityRecord) msg.obj;
1648                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1649                    }
1650                    if (nextState) {
1651                        mUpdateLock.acquire();
1652                    } else {
1653                        mUpdateLock.release();
1654                    }
1655                }
1656                break;
1657            }
1658            case PERSIST_URI_GRANTS_MSG: {
1659                writeGrantedUriPermissions();
1660                break;
1661            }
1662            case REQUEST_ALL_PSS_MSG: {
1663                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1664                break;
1665            }
1666            case START_PROFILES_MSG: {
1667                synchronized (ActivityManagerService.this) {
1668                    startProfilesLocked();
1669                }
1670                break;
1671            }
1672            case UPDATE_TIME: {
1673                synchronized (ActivityManagerService.this) {
1674                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1675                        ProcessRecord r = mLruProcesses.get(i);
1676                        if (r.thread != null) {
1677                            try {
1678                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1679                            } catch (RemoteException ex) {
1680                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1681                            }
1682                        }
1683                    }
1684                }
1685                break;
1686            }
1687            case SYSTEM_USER_START_MSG: {
1688                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1689                        Integer.toString(msg.arg1), msg.arg1);
1690                mSystemServiceManager.startUser(msg.arg1);
1691                break;
1692            }
1693            case SYSTEM_USER_CURRENT_MSG: {
1694                mBatteryStatsService.noteEvent(
1695                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1696                        Integer.toString(msg.arg2), msg.arg2);
1697                mBatteryStatsService.noteEvent(
1698                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1699                        Integer.toString(msg.arg1), msg.arg1);
1700                mSystemServiceManager.switchUser(msg.arg1);
1701                break;
1702            }
1703            case ENTER_ANIMATION_COMPLETE_MSG: {
1704                synchronized (ActivityManagerService.this) {
1705                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1706                    if (r != null && r.app != null && r.app.thread != null) {
1707                        try {
1708                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1709                        } catch (RemoteException e) {
1710                        }
1711                    }
1712                }
1713                break;
1714            }
1715            case FINISH_BOOTING_MSG: {
1716                if (msg.arg1 != 0) {
1717                    finishBooting();
1718                }
1719                if (msg.arg2 != 0) {
1720                    enableScreenAfterBoot();
1721                }
1722                break;
1723            }
1724            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1725                try {
1726                    Locale l = (Locale) msg.obj;
1727                    IBinder service = ServiceManager.getService("mount");
1728                    IMountService mountService = IMountService.Stub.asInterface(service);
1729                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1730                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1731                } catch (RemoteException e) {
1732                    Log.e(TAG, "Error storing locale for decryption UI", e);
1733                }
1734                break;
1735            }
1736            case DISMISS_DIALOG_MSG: {
1737                final Dialog d = (Dialog) msg.obj;
1738                d.dismiss();
1739                break;
1740            }
1741            }
1742        }
1743    };
1744
1745    static final int COLLECT_PSS_BG_MSG = 1;
1746
1747    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1748        @Override
1749        public void handleMessage(Message msg) {
1750            switch (msg.what) {
1751            case COLLECT_PSS_BG_MSG: {
1752                long start = SystemClock.uptimeMillis();
1753                MemInfoReader memInfo = null;
1754                synchronized (ActivityManagerService.this) {
1755                    if (mFullPssPending) {
1756                        mFullPssPending = false;
1757                        memInfo = new MemInfoReader();
1758                    }
1759                }
1760                if (memInfo != null) {
1761                    updateCpuStatsNow();
1762                    long nativeTotalPss = 0;
1763                    synchronized (mProcessCpuTracker) {
1764                        final int N = mProcessCpuTracker.countStats();
1765                        for (int j=0; j<N; j++) {
1766                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1767                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1768                                // This is definitely an application process; skip it.
1769                                continue;
1770                            }
1771                            synchronized (mPidsSelfLocked) {
1772                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1773                                    // This is one of our own processes; skip it.
1774                                    continue;
1775                                }
1776                            }
1777                            nativeTotalPss += Debug.getPss(st.pid, null);
1778                        }
1779                    }
1780                    memInfo.readMemInfo();
1781                    synchronized (ActivityManagerService.this) {
1782                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1783                                + (SystemClock.uptimeMillis()-start) + "ms");
1784                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1785                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1786                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1787                    }
1788                }
1789
1790                int i = 0;
1791                int num = 0;
1792                long[] tmp = new long[1];
1793                do {
1794                    ProcessRecord proc;
1795                    int procState;
1796                    int pid;
1797                    synchronized (ActivityManagerService.this) {
1798                        if (i >= mPendingPssProcesses.size()) {
1799                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1800                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1801                            mPendingPssProcesses.clear();
1802                            return;
1803                        }
1804                        proc = mPendingPssProcesses.get(i);
1805                        procState = proc.pssProcState;
1806                        if (proc.thread != null && procState == proc.setProcState) {
1807                            pid = proc.pid;
1808                        } else {
1809                            proc = null;
1810                            pid = 0;
1811                        }
1812                        i++;
1813                    }
1814                    if (proc != null) {
1815                        long pss = Debug.getPss(pid, tmp);
1816                        synchronized (ActivityManagerService.this) {
1817                            if (proc.thread != null && proc.setProcState == procState
1818                                    && proc.pid == pid) {
1819                                num++;
1820                                proc.lastPssTime = SystemClock.uptimeMillis();
1821                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1822                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1823                                        + ": " + pss + " lastPss=" + proc.lastPss
1824                                        + " state=" + ProcessList.makeProcStateString(procState));
1825                                if (proc.initialIdlePss == 0) {
1826                                    proc.initialIdlePss = pss;
1827                                }
1828                                proc.lastPss = pss;
1829                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1830                                    proc.lastCachedPss = pss;
1831                                }
1832                            }
1833                        }
1834                    }
1835                } while (true);
1836            }
1837            }
1838        }
1839    };
1840
1841    public void setSystemProcess() {
1842        try {
1843            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1844            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1845            ServiceManager.addService("meminfo", new MemBinder(this));
1846            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1847            ServiceManager.addService("dbinfo", new DbBinder(this));
1848            if (MONITOR_CPU_USAGE) {
1849                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1850            }
1851            ServiceManager.addService("permission", new PermissionController(this));
1852
1853            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1854                    "android", STOCK_PM_FLAGS);
1855            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1856
1857            synchronized (this) {
1858                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1859                app.persistent = true;
1860                app.pid = MY_PID;
1861                app.maxAdj = ProcessList.SYSTEM_ADJ;
1862                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1863                mProcessNames.put(app.processName, app.uid, app);
1864                synchronized (mPidsSelfLocked) {
1865                    mPidsSelfLocked.put(app.pid, app);
1866                }
1867                updateLruProcessLocked(app, false, null);
1868                updateOomAdjLocked();
1869            }
1870        } catch (PackageManager.NameNotFoundException e) {
1871            throw new RuntimeException(
1872                    "Unable to find android system package", e);
1873        }
1874    }
1875
1876    public void setWindowManager(WindowManagerService wm) {
1877        mWindowManager = wm;
1878        mStackSupervisor.setWindowManager(wm);
1879    }
1880
1881    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1882        mUsageStatsService = usageStatsManager;
1883    }
1884
1885    public void startObservingNativeCrashes() {
1886        final NativeCrashListener ncl = new NativeCrashListener(this);
1887        ncl.start();
1888    }
1889
1890    public IAppOpsService getAppOpsService() {
1891        return mAppOpsService;
1892    }
1893
1894    static class MemBinder extends Binder {
1895        ActivityManagerService mActivityManagerService;
1896        MemBinder(ActivityManagerService activityManagerService) {
1897            mActivityManagerService = activityManagerService;
1898        }
1899
1900        @Override
1901        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1902            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1903                    != PackageManager.PERMISSION_GRANTED) {
1904                pw.println("Permission Denial: can't dump meminfo from from pid="
1905                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1906                        + " without permission " + android.Manifest.permission.DUMP);
1907                return;
1908            }
1909
1910            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1911        }
1912    }
1913
1914    static class GraphicsBinder extends Binder {
1915        ActivityManagerService mActivityManagerService;
1916        GraphicsBinder(ActivityManagerService activityManagerService) {
1917            mActivityManagerService = activityManagerService;
1918        }
1919
1920        @Override
1921        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1922            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1923                    != PackageManager.PERMISSION_GRANTED) {
1924                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1925                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1926                        + " without permission " + android.Manifest.permission.DUMP);
1927                return;
1928            }
1929
1930            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1931        }
1932    }
1933
1934    static class DbBinder extends Binder {
1935        ActivityManagerService mActivityManagerService;
1936        DbBinder(ActivityManagerService activityManagerService) {
1937            mActivityManagerService = activityManagerService;
1938        }
1939
1940        @Override
1941        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1942            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1943                    != PackageManager.PERMISSION_GRANTED) {
1944                pw.println("Permission Denial: can't dump dbinfo from from pid="
1945                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1946                        + " without permission " + android.Manifest.permission.DUMP);
1947                return;
1948            }
1949
1950            mActivityManagerService.dumpDbInfo(fd, pw, args);
1951        }
1952    }
1953
1954    static class CpuBinder extends Binder {
1955        ActivityManagerService mActivityManagerService;
1956        CpuBinder(ActivityManagerService activityManagerService) {
1957            mActivityManagerService = activityManagerService;
1958        }
1959
1960        @Override
1961        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1962            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1963                    != PackageManager.PERMISSION_GRANTED) {
1964                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1965                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1966                        + " without permission " + android.Manifest.permission.DUMP);
1967                return;
1968            }
1969
1970            synchronized (mActivityManagerService.mProcessCpuTracker) {
1971                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1972                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1973                        SystemClock.uptimeMillis()));
1974            }
1975        }
1976    }
1977
1978    public static final class Lifecycle extends SystemService {
1979        private final ActivityManagerService mService;
1980
1981        public Lifecycle(Context context) {
1982            super(context);
1983            mService = new ActivityManagerService(context);
1984        }
1985
1986        @Override
1987        public void onStart() {
1988            mService.start();
1989        }
1990
1991        public ActivityManagerService getService() {
1992            return mService;
1993        }
1994    }
1995
1996    // Note: This method is invoked on the main thread but may need to attach various
1997    // handlers to other threads.  So take care to be explicit about the looper.
1998    public ActivityManagerService(Context systemContext) {
1999        mContext = systemContext;
2000        mFactoryTest = FactoryTest.getMode();
2001        mSystemThread = ActivityThread.currentActivityThread();
2002
2003        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2004
2005        mHandlerThread = new ServiceThread(TAG,
2006                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2007        mHandlerThread.start();
2008        mHandler = new MainHandler(mHandlerThread.getLooper());
2009
2010        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2011                "foreground", BROADCAST_FG_TIMEOUT, false);
2012        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2013                "background", BROADCAST_BG_TIMEOUT, true);
2014        mBroadcastQueues[0] = mFgBroadcastQueue;
2015        mBroadcastQueues[1] = mBgBroadcastQueue;
2016
2017        mServices = new ActiveServices(this);
2018        mProviderMap = new ProviderMap(this);
2019
2020        // TODO: Move creation of battery stats service outside of activity manager service.
2021        File dataDir = Environment.getDataDirectory();
2022        File systemDir = new File(dataDir, "system");
2023        systemDir.mkdirs();
2024        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2025        mBatteryStatsService.getActiveStatistics().readLocked();
2026        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2027        mOnBattery = DEBUG_POWER ? true
2028                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2029        mBatteryStatsService.getActiveStatistics().setCallback(this);
2030
2031        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2032
2033        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2034
2035        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2036
2037        // User 0 is the first and only user that runs at boot.
2038        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2039        mUserLru.add(Integer.valueOf(0));
2040        updateStartedUserArrayLocked();
2041
2042        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2043            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2044
2045        mConfiguration.setToDefaults();
2046        mConfiguration.setLocale(Locale.getDefault());
2047
2048        mConfigurationSeq = mConfiguration.seq = 1;
2049        mProcessCpuTracker.init();
2050
2051        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2052        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2053        mStackSupervisor = new ActivityStackSupervisor(this);
2054        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2055
2056        mProcessCpuThread = new Thread("CpuTracker") {
2057            @Override
2058            public void run() {
2059                while (true) {
2060                    try {
2061                        try {
2062                            synchronized(this) {
2063                                final long now = SystemClock.uptimeMillis();
2064                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2065                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2066                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2067                                //        + ", write delay=" + nextWriteDelay);
2068                                if (nextWriteDelay < nextCpuDelay) {
2069                                    nextCpuDelay = nextWriteDelay;
2070                                }
2071                                if (nextCpuDelay > 0) {
2072                                    mProcessCpuMutexFree.set(true);
2073                                    this.wait(nextCpuDelay);
2074                                }
2075                            }
2076                        } catch (InterruptedException e) {
2077                        }
2078                        updateCpuStatsNow();
2079                    } catch (Exception e) {
2080                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2081                    }
2082                }
2083            }
2084        };
2085
2086        Watchdog.getInstance().addMonitor(this);
2087        Watchdog.getInstance().addThread(mHandler);
2088    }
2089
2090    public void setSystemServiceManager(SystemServiceManager mgr) {
2091        mSystemServiceManager = mgr;
2092    }
2093
2094    public void setInstaller(Installer installer) {
2095        mInstaller = installer;
2096    }
2097
2098    private void start() {
2099        Process.removeAllProcessGroups();
2100        mProcessCpuThread.start();
2101
2102        mBatteryStatsService.publish(mContext);
2103        mAppOpsService.publish(mContext);
2104        Slog.d("AppOps", "AppOpsService published");
2105        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2106    }
2107
2108    public void initPowerManagement() {
2109        mStackSupervisor.initPowerManagement();
2110        mBatteryStatsService.initPowerManagement();
2111    }
2112
2113    @Override
2114    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2115            throws RemoteException {
2116        if (code == SYSPROPS_TRANSACTION) {
2117            // We need to tell all apps about the system property change.
2118            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2119            synchronized(this) {
2120                final int NP = mProcessNames.getMap().size();
2121                for (int ip=0; ip<NP; ip++) {
2122                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2123                    final int NA = apps.size();
2124                    for (int ia=0; ia<NA; ia++) {
2125                        ProcessRecord app = apps.valueAt(ia);
2126                        if (app.thread != null) {
2127                            procs.add(app.thread.asBinder());
2128                        }
2129                    }
2130                }
2131            }
2132
2133            int N = procs.size();
2134            for (int i=0; i<N; i++) {
2135                Parcel data2 = Parcel.obtain();
2136                try {
2137                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2138                } catch (RemoteException e) {
2139                }
2140                data2.recycle();
2141            }
2142        }
2143        try {
2144            return super.onTransact(code, data, reply, flags);
2145        } catch (RuntimeException e) {
2146            // The activity manager only throws security exceptions, so let's
2147            // log all others.
2148            if (!(e instanceof SecurityException)) {
2149                Slog.wtf(TAG, "Activity Manager Crash", e);
2150            }
2151            throw e;
2152        }
2153    }
2154
2155    void updateCpuStats() {
2156        final long now = SystemClock.uptimeMillis();
2157        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2158            return;
2159        }
2160        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2161            synchronized (mProcessCpuThread) {
2162                mProcessCpuThread.notify();
2163            }
2164        }
2165    }
2166
2167    void updateCpuStatsNow() {
2168        synchronized (mProcessCpuTracker) {
2169            mProcessCpuMutexFree.set(false);
2170            final long now = SystemClock.uptimeMillis();
2171            boolean haveNewCpuStats = false;
2172
2173            if (MONITOR_CPU_USAGE &&
2174                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2175                mLastCpuTime.set(now);
2176                haveNewCpuStats = true;
2177                mProcessCpuTracker.update();
2178                //Slog.i(TAG, mProcessCpu.printCurrentState());
2179                //Slog.i(TAG, "Total CPU usage: "
2180                //        + mProcessCpu.getTotalCpuPercent() + "%");
2181
2182                // Slog the cpu usage if the property is set.
2183                if ("true".equals(SystemProperties.get("events.cpu"))) {
2184                    int user = mProcessCpuTracker.getLastUserTime();
2185                    int system = mProcessCpuTracker.getLastSystemTime();
2186                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2187                    int irq = mProcessCpuTracker.getLastIrqTime();
2188                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2189                    int idle = mProcessCpuTracker.getLastIdleTime();
2190
2191                    int total = user + system + iowait + irq + softIrq + idle;
2192                    if (total == 0) total = 1;
2193
2194                    EventLog.writeEvent(EventLogTags.CPU,
2195                            ((user+system+iowait+irq+softIrq) * 100) / total,
2196                            (user * 100) / total,
2197                            (system * 100) / total,
2198                            (iowait * 100) / total,
2199                            (irq * 100) / total,
2200                            (softIrq * 100) / total);
2201                }
2202            }
2203
2204            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2205            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2206            synchronized(bstats) {
2207                synchronized(mPidsSelfLocked) {
2208                    if (haveNewCpuStats) {
2209                        if (mOnBattery) {
2210                            int perc = bstats.startAddingCpuLocked();
2211                            int totalUTime = 0;
2212                            int totalSTime = 0;
2213                            final int N = mProcessCpuTracker.countStats();
2214                            for (int i=0; i<N; i++) {
2215                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2216                                if (!st.working) {
2217                                    continue;
2218                                }
2219                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2220                                int otherUTime = (st.rel_utime*perc)/100;
2221                                int otherSTime = (st.rel_stime*perc)/100;
2222                                totalUTime += otherUTime;
2223                                totalSTime += otherSTime;
2224                                if (pr != null) {
2225                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2226                                    if (ps == null || !ps.isActive()) {
2227                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2228                                                pr.info.uid, pr.processName);
2229                                    }
2230                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2231                                            st.rel_stime-otherSTime);
2232                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2233                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2234                                } else {
2235                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2236                                    if (ps == null || !ps.isActive()) {
2237                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2238                                                bstats.mapUid(st.uid), st.name);
2239                                    }
2240                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2241                                            st.rel_stime-otherSTime);
2242                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2243                                }
2244                            }
2245                            bstats.finishAddingCpuLocked(perc, totalUTime,
2246                                    totalSTime, cpuSpeedTimes);
2247                        }
2248                    }
2249                }
2250
2251                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2252                    mLastWriteTime = now;
2253                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2254                }
2255            }
2256        }
2257    }
2258
2259    @Override
2260    public void batteryNeedsCpuUpdate() {
2261        updateCpuStatsNow();
2262    }
2263
2264    @Override
2265    public void batteryPowerChanged(boolean onBattery) {
2266        // When plugging in, update the CPU stats first before changing
2267        // the plug state.
2268        updateCpuStatsNow();
2269        synchronized (this) {
2270            synchronized(mPidsSelfLocked) {
2271                mOnBattery = DEBUG_POWER ? true : onBattery;
2272            }
2273        }
2274    }
2275
2276    /**
2277     * Initialize the application bind args. These are passed to each
2278     * process when the bindApplication() IPC is sent to the process. They're
2279     * lazily setup to make sure the services are running when they're asked for.
2280     */
2281    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2282        if (mAppBindArgs == null) {
2283            mAppBindArgs = new HashMap<>();
2284
2285            // Isolated processes won't get this optimization, so that we don't
2286            // violate the rules about which services they have access to.
2287            if (!isolated) {
2288                // Setup the application init args
2289                mAppBindArgs.put("package", ServiceManager.getService("package"));
2290                mAppBindArgs.put("window", ServiceManager.getService("window"));
2291                mAppBindArgs.put(Context.ALARM_SERVICE,
2292                        ServiceManager.getService(Context.ALARM_SERVICE));
2293            }
2294        }
2295        return mAppBindArgs;
2296    }
2297
2298    final void setFocusedActivityLocked(ActivityRecord r) {
2299        if (mFocusedActivity != r) {
2300            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2301            mFocusedActivity = r;
2302            if (r.task != null && r.task.voiceInteractor != null) {
2303                startRunningVoiceLocked();
2304            } else {
2305                finishRunningVoiceLocked();
2306            }
2307            mStackSupervisor.setFocusedStack(r);
2308            if (r != null) {
2309                mWindowManager.setFocusedApp(r.appToken, true);
2310            }
2311            applyUpdateLockStateLocked(r);
2312        }
2313    }
2314
2315    final void clearFocusedActivity(ActivityRecord r) {
2316        if (mFocusedActivity == r) {
2317            mFocusedActivity = null;
2318        }
2319    }
2320
2321    @Override
2322    public void setFocusedStack(int stackId) {
2323        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2324        synchronized (ActivityManagerService.this) {
2325            ActivityStack stack = mStackSupervisor.getStack(stackId);
2326            if (stack != null) {
2327                ActivityRecord r = stack.topRunningActivityLocked(null);
2328                if (r != null) {
2329                    setFocusedActivityLocked(r);
2330                }
2331            }
2332        }
2333    }
2334
2335    @Override
2336    public void notifyActivityDrawn(IBinder token) {
2337        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2338        synchronized (this) {
2339            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2340            if (r != null) {
2341                r.task.stack.notifyActivityDrawnLocked(r);
2342            }
2343        }
2344    }
2345
2346    final void applyUpdateLockStateLocked(ActivityRecord r) {
2347        // Modifications to the UpdateLock state are done on our handler, outside
2348        // the activity manager's locks.  The new state is determined based on the
2349        // state *now* of the relevant activity record.  The object is passed to
2350        // the handler solely for logging detail, not to be consulted/modified.
2351        final boolean nextState = r != null && r.immersive;
2352        mHandler.sendMessage(
2353                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2354    }
2355
2356    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2357        Message msg = Message.obtain();
2358        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2359        msg.obj = r.task.askedCompatMode ? null : r;
2360        mHandler.sendMessage(msg);
2361    }
2362
2363    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2364            String what, Object obj, ProcessRecord srcApp) {
2365        app.lastActivityTime = now;
2366
2367        if (app.activities.size() > 0) {
2368            // Don't want to touch dependent processes that are hosting activities.
2369            return index;
2370        }
2371
2372        int lrui = mLruProcesses.lastIndexOf(app);
2373        if (lrui < 0) {
2374            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2375                    + what + " " + obj + " from " + srcApp);
2376            return index;
2377        }
2378
2379        if (lrui >= index) {
2380            // Don't want to cause this to move dependent processes *back* in the
2381            // list as if they were less frequently used.
2382            return index;
2383        }
2384
2385        if (lrui >= mLruProcessActivityStart) {
2386            // Don't want to touch dependent processes that are hosting activities.
2387            return index;
2388        }
2389
2390        mLruProcesses.remove(lrui);
2391        if (index > 0) {
2392            index--;
2393        }
2394        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2395                + " in LRU list: " + app);
2396        mLruProcesses.add(index, app);
2397        return index;
2398    }
2399
2400    final void removeLruProcessLocked(ProcessRecord app) {
2401        int lrui = mLruProcesses.lastIndexOf(app);
2402        if (lrui >= 0) {
2403            if (!app.killed) {
2404                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2405                Process.killProcessQuiet(app.pid);
2406                Process.killProcessGroup(app.info.uid, app.pid);
2407            }
2408            if (lrui <= mLruProcessActivityStart) {
2409                mLruProcessActivityStart--;
2410            }
2411            if (lrui <= mLruProcessServiceStart) {
2412                mLruProcessServiceStart--;
2413            }
2414            mLruProcesses.remove(lrui);
2415        }
2416    }
2417
2418    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2419            ProcessRecord client) {
2420        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2421                || app.treatLikeActivity;
2422        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2423        if (!activityChange && hasActivity) {
2424            // The process has activities, so we are only allowing activity-based adjustments
2425            // to move it.  It should be kept in the front of the list with other
2426            // processes that have activities, and we don't want those to change their
2427            // order except due to activity operations.
2428            return;
2429        }
2430
2431        mLruSeq++;
2432        final long now = SystemClock.uptimeMillis();
2433        app.lastActivityTime = now;
2434
2435        // First a quick reject: if the app is already at the position we will
2436        // put it, then there is nothing to do.
2437        if (hasActivity) {
2438            final int N = mLruProcesses.size();
2439            if (N > 0 && mLruProcesses.get(N-1) == app) {
2440                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2441                return;
2442            }
2443        } else {
2444            if (mLruProcessServiceStart > 0
2445                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2446                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2447                return;
2448            }
2449        }
2450
2451        int lrui = mLruProcesses.lastIndexOf(app);
2452
2453        if (app.persistent && lrui >= 0) {
2454            // We don't care about the position of persistent processes, as long as
2455            // they are in the list.
2456            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2457            return;
2458        }
2459
2460        /* In progress: compute new position first, so we can avoid doing work
2461           if the process is not actually going to move.  Not yet working.
2462        int addIndex;
2463        int nextIndex;
2464        boolean inActivity = false, inService = false;
2465        if (hasActivity) {
2466            // Process has activities, put it at the very tipsy-top.
2467            addIndex = mLruProcesses.size();
2468            nextIndex = mLruProcessServiceStart;
2469            inActivity = true;
2470        } else if (hasService) {
2471            // Process has services, put it at the top of the service list.
2472            addIndex = mLruProcessActivityStart;
2473            nextIndex = mLruProcessServiceStart;
2474            inActivity = true;
2475            inService = true;
2476        } else  {
2477            // Process not otherwise of interest, it goes to the top of the non-service area.
2478            addIndex = mLruProcessServiceStart;
2479            if (client != null) {
2480                int clientIndex = mLruProcesses.lastIndexOf(client);
2481                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2482                        + app);
2483                if (clientIndex >= 0 && addIndex > clientIndex) {
2484                    addIndex = clientIndex;
2485                }
2486            }
2487            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2488        }
2489
2490        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2491                + mLruProcessActivityStart + "): " + app);
2492        */
2493
2494        if (lrui >= 0) {
2495            if (lrui < mLruProcessActivityStart) {
2496                mLruProcessActivityStart--;
2497            }
2498            if (lrui < mLruProcessServiceStart) {
2499                mLruProcessServiceStart--;
2500            }
2501            /*
2502            if (addIndex > lrui) {
2503                addIndex--;
2504            }
2505            if (nextIndex > lrui) {
2506                nextIndex--;
2507            }
2508            */
2509            mLruProcesses.remove(lrui);
2510        }
2511
2512        /*
2513        mLruProcesses.add(addIndex, app);
2514        if (inActivity) {
2515            mLruProcessActivityStart++;
2516        }
2517        if (inService) {
2518            mLruProcessActivityStart++;
2519        }
2520        */
2521
2522        int nextIndex;
2523        if (hasActivity) {
2524            final int N = mLruProcesses.size();
2525            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2526                // Process doesn't have activities, but has clients with
2527                // activities...  move it up, but one below the top (the top
2528                // should always have a real activity).
2529                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2530                mLruProcesses.add(N-1, app);
2531                // To keep it from spamming the LRU list (by making a bunch of clients),
2532                // we will push down any other entries owned by the app.
2533                final int uid = app.info.uid;
2534                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2535                    ProcessRecord subProc = mLruProcesses.get(i);
2536                    if (subProc.info.uid == uid) {
2537                        // We want to push this one down the list.  If the process after
2538                        // it is for the same uid, however, don't do so, because we don't
2539                        // want them internally to be re-ordered.
2540                        if (mLruProcesses.get(i-1).info.uid != uid) {
2541                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2542                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2543                            ProcessRecord tmp = mLruProcesses.get(i);
2544                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2545                            mLruProcesses.set(i-1, tmp);
2546                            i--;
2547                        }
2548                    } else {
2549                        // A gap, we can stop here.
2550                        break;
2551                    }
2552                }
2553            } else {
2554                // Process has activities, put it at the very tipsy-top.
2555                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2556                mLruProcesses.add(app);
2557            }
2558            nextIndex = mLruProcessServiceStart;
2559        } else if (hasService) {
2560            // Process has services, put it at the top of the service list.
2561            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2562            mLruProcesses.add(mLruProcessActivityStart, app);
2563            nextIndex = mLruProcessServiceStart;
2564            mLruProcessActivityStart++;
2565        } else  {
2566            // Process not otherwise of interest, it goes to the top of the non-service area.
2567            int index = mLruProcessServiceStart;
2568            if (client != null) {
2569                // If there is a client, don't allow the process to be moved up higher
2570                // in the list than that client.
2571                int clientIndex = mLruProcesses.lastIndexOf(client);
2572                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2573                        + " when updating " + app);
2574                if (clientIndex <= lrui) {
2575                    // Don't allow the client index restriction to push it down farther in the
2576                    // list than it already is.
2577                    clientIndex = lrui;
2578                }
2579                if (clientIndex >= 0 && index > clientIndex) {
2580                    index = clientIndex;
2581                }
2582            }
2583            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2584            mLruProcesses.add(index, app);
2585            nextIndex = index-1;
2586            mLruProcessActivityStart++;
2587            mLruProcessServiceStart++;
2588        }
2589
2590        // If the app is currently using a content provider or service,
2591        // bump those processes as well.
2592        for (int j=app.connections.size()-1; j>=0; j--) {
2593            ConnectionRecord cr = app.connections.valueAt(j);
2594            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2595                    && cr.binding.service.app != null
2596                    && cr.binding.service.app.lruSeq != mLruSeq
2597                    && !cr.binding.service.app.persistent) {
2598                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2599                        "service connection", cr, app);
2600            }
2601        }
2602        for (int j=app.conProviders.size()-1; j>=0; j--) {
2603            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2604            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2605                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2606                        "provider reference", cpr, app);
2607            }
2608        }
2609    }
2610
2611    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2612        if (uid == Process.SYSTEM_UID) {
2613            // The system gets to run in any process.  If there are multiple
2614            // processes with the same uid, just pick the first (this
2615            // should never happen).
2616            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2617            if (procs == null) return null;
2618            final int N = procs.size();
2619            for (int i = 0; i < N; i++) {
2620                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2621            }
2622        }
2623        ProcessRecord proc = mProcessNames.get(processName, uid);
2624        if (false && proc != null && !keepIfLarge
2625                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2626                && proc.lastCachedPss >= 4000) {
2627            // Turn this condition on to cause killing to happen regularly, for testing.
2628            if (proc.baseProcessTracker != null) {
2629                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2630            }
2631            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2632        } else if (proc != null && !keepIfLarge
2633                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2634                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2635            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2636            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2637                if (proc.baseProcessTracker != null) {
2638                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2639                }
2640                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2641            }
2642        }
2643        return proc;
2644    }
2645
2646    void ensurePackageDexOpt(String packageName) {
2647        IPackageManager pm = AppGlobals.getPackageManager();
2648        try {
2649            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2650                mDidDexOpt = true;
2651            }
2652        } catch (RemoteException e) {
2653        }
2654    }
2655
2656    boolean isNextTransitionForward() {
2657        int transit = mWindowManager.getPendingAppTransition();
2658        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2659                || transit == AppTransition.TRANSIT_TASK_OPEN
2660                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2661    }
2662
2663    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2664            String processName, String abiOverride, int uid, Runnable crashHandler) {
2665        synchronized(this) {
2666            ApplicationInfo info = new ApplicationInfo();
2667            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2668            // For isolated processes, the former contains the parent's uid and the latter the
2669            // actual uid of the isolated process.
2670            // In the special case introduced by this method (which is, starting an isolated
2671            // process directly from the SystemServer without an actual parent app process) the
2672            // closest thing to a parent's uid is SYSTEM_UID.
2673            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2674            // the |isolated| logic in the ProcessRecord constructor.
2675            info.uid = Process.SYSTEM_UID;
2676            info.processName = processName;
2677            info.className = entryPoint;
2678            info.packageName = "android";
2679            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2680                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2681                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2682                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2683                    crashHandler);
2684            return proc != null ? proc.pid : 0;
2685        }
2686    }
2687
2688    final ProcessRecord startProcessLocked(String processName,
2689            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2690            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2691            boolean isolated, boolean keepIfLarge) {
2692        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2693                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2694                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2695                null /* crashHandler */);
2696    }
2697
2698    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2699            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2700            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2701            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2702        long startTime = SystemClock.elapsedRealtime();
2703        ProcessRecord app;
2704        if (!isolated) {
2705            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2706            checkTime(startTime, "startProcess: after getProcessRecord");
2707        } else {
2708            // If this is an isolated process, it can't re-use an existing process.
2709            app = null;
2710        }
2711        // We don't have to do anything more if:
2712        // (1) There is an existing application record; and
2713        // (2) The caller doesn't think it is dead, OR there is no thread
2714        //     object attached to it so we know it couldn't have crashed; and
2715        // (3) There is a pid assigned to it, so it is either starting or
2716        //     already running.
2717        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2718                + " app=" + app + " knownToBeDead=" + knownToBeDead
2719                + " thread=" + (app != null ? app.thread : null)
2720                + " pid=" + (app != null ? app.pid : -1));
2721        if (app != null && app.pid > 0) {
2722            if (!knownToBeDead || app.thread == null) {
2723                // We already have the app running, or are waiting for it to
2724                // come up (we have a pid but not yet its thread), so keep it.
2725                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2726                // If this is a new package in the process, add the package to the list
2727                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2728                checkTime(startTime, "startProcess: done, added package to proc");
2729                return app;
2730            }
2731
2732            // An application record is attached to a previous process,
2733            // clean it up now.
2734            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2735            checkTime(startTime, "startProcess: bad proc running, killing");
2736            Process.killProcessGroup(app.info.uid, app.pid);
2737            handleAppDiedLocked(app, true, true);
2738            checkTime(startTime, "startProcess: done killing old proc");
2739        }
2740
2741        String hostingNameStr = hostingName != null
2742                ? hostingName.flattenToShortString() : null;
2743
2744        if (!isolated) {
2745            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2746                // If we are in the background, then check to see if this process
2747                // is bad.  If so, we will just silently fail.
2748                if (mBadProcesses.get(info.processName, info.uid) != null) {
2749                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2750                            + "/" + info.processName);
2751                    return null;
2752                }
2753            } else {
2754                // When the user is explicitly starting a process, then clear its
2755                // crash count so that we won't make it bad until they see at
2756                // least one crash dialog again, and make the process good again
2757                // if it had been bad.
2758                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2759                        + "/" + info.processName);
2760                mProcessCrashTimes.remove(info.processName, info.uid);
2761                if (mBadProcesses.get(info.processName, info.uid) != null) {
2762                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2763                            UserHandle.getUserId(info.uid), info.uid,
2764                            info.processName);
2765                    mBadProcesses.remove(info.processName, info.uid);
2766                    if (app != null) {
2767                        app.bad = false;
2768                    }
2769                }
2770            }
2771        }
2772
2773        if (app == null) {
2774            checkTime(startTime, "startProcess: creating new process record");
2775            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2776            app.crashHandler = crashHandler;
2777            if (app == null) {
2778                Slog.w(TAG, "Failed making new process record for "
2779                        + processName + "/" + info.uid + " isolated=" + isolated);
2780                return null;
2781            }
2782            mProcessNames.put(processName, app.uid, app);
2783            if (isolated) {
2784                mIsolatedProcesses.put(app.uid, app);
2785            }
2786            checkTime(startTime, "startProcess: done creating new process record");
2787        } else {
2788            // If this is a new package in the process, add the package to the list
2789            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2790            checkTime(startTime, "startProcess: added package to existing proc");
2791        }
2792
2793        // If the system is not ready yet, then hold off on starting this
2794        // process until it is.
2795        if (!mProcessesReady
2796                && !isAllowedWhileBooting(info)
2797                && !allowWhileBooting) {
2798            if (!mProcessesOnHold.contains(app)) {
2799                mProcessesOnHold.add(app);
2800            }
2801            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2802            checkTime(startTime, "startProcess: returning with proc on hold");
2803            return app;
2804        }
2805
2806        checkTime(startTime, "startProcess: stepping in to startProcess");
2807        startProcessLocked(
2808                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2809        checkTime(startTime, "startProcess: done starting proc!");
2810        return (app.pid != 0) ? app : null;
2811    }
2812
2813    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2814        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2815    }
2816
2817    private final void startProcessLocked(ProcessRecord app,
2818            String hostingType, String hostingNameStr) {
2819        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2820                null /* entryPoint */, null /* entryPointArgs */);
2821    }
2822
2823    private final void startProcessLocked(ProcessRecord app, String hostingType,
2824            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2825        long startTime = SystemClock.elapsedRealtime();
2826        if (app.pid > 0 && app.pid != MY_PID) {
2827            checkTime(startTime, "startProcess: removing from pids map");
2828            synchronized (mPidsSelfLocked) {
2829                mPidsSelfLocked.remove(app.pid);
2830                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2831            }
2832            checkTime(startTime, "startProcess: done removing from pids map");
2833            app.setPid(0);
2834        }
2835
2836        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2837                "startProcessLocked removing on hold: " + app);
2838        mProcessesOnHold.remove(app);
2839
2840        checkTime(startTime, "startProcess: starting to update cpu stats");
2841        updateCpuStats();
2842        checkTime(startTime, "startProcess: done updating cpu stats");
2843
2844        try {
2845            int uid = app.uid;
2846
2847            int[] gids = null;
2848            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2849            if (!app.isolated) {
2850                int[] permGids = null;
2851                try {
2852                    checkTime(startTime, "startProcess: getting gids from package manager");
2853                    final PackageManager pm = mContext.getPackageManager();
2854                    permGids = pm.getPackageGids(app.info.packageName);
2855
2856                    if (Environment.isExternalStorageEmulated()) {
2857                        checkTime(startTime, "startProcess: checking external storage perm");
2858                        if (pm.checkPermission(
2859                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2860                                app.info.packageName) == PERMISSION_GRANTED) {
2861                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2862                        } else {
2863                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2864                        }
2865                    }
2866                } catch (PackageManager.NameNotFoundException e) {
2867                    Slog.w(TAG, "Unable to retrieve gids", e);
2868                }
2869
2870                /*
2871                 * Add shared application and profile GIDs so applications can share some
2872                 * resources like shared libraries and access user-wide resources
2873                 */
2874                if (permGids == null) {
2875                    gids = new int[2];
2876                } else {
2877                    gids = new int[permGids.length + 2];
2878                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2879                }
2880                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2881                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2882            }
2883            checkTime(startTime, "startProcess: building args");
2884            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2885                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2886                        && mTopComponent != null
2887                        && app.processName.equals(mTopComponent.getPackageName())) {
2888                    uid = 0;
2889                }
2890                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2891                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2892                    uid = 0;
2893                }
2894            }
2895            int debugFlags = 0;
2896            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2897                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2898                // Also turn on CheckJNI for debuggable apps. It's quite
2899                // awkward to turn on otherwise.
2900                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2901            }
2902            // Run the app in safe mode if its manifest requests so or the
2903            // system is booted in safe mode.
2904            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2905                mSafeMode == true) {
2906                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2907            }
2908            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2909                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2910            }
2911            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2912                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2913            }
2914            if ("1".equals(SystemProperties.get("debug.assert"))) {
2915                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2916            }
2917
2918            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2919            if (requiredAbi == null) {
2920                requiredAbi = Build.SUPPORTED_ABIS[0];
2921            }
2922
2923            String instructionSet = null;
2924            if (app.info.primaryCpuAbi != null) {
2925                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2926            }
2927
2928            // Start the process.  It will either succeed and return a result containing
2929            // the PID of the new process, or else throw a RuntimeException.
2930            boolean isActivityProcess = (entryPoint == null);
2931            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2932            checkTime(startTime, "startProcess: asking zygote to start proc");
2933            Process.ProcessStartResult startResult = Process.start(entryPoint,
2934                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2935                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2936                    app.info.dataDir, entryPointArgs);
2937            checkTime(startTime, "startProcess: returned from zygote!");
2938
2939            if (app.isolated) {
2940                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2941            }
2942            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2943            checkTime(startTime, "startProcess: done updating battery stats");
2944
2945            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2946                    UserHandle.getUserId(uid), startResult.pid, uid,
2947                    app.processName, hostingType,
2948                    hostingNameStr != null ? hostingNameStr : "");
2949
2950            if (app.persistent) {
2951                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2952            }
2953
2954            checkTime(startTime, "startProcess: building log message");
2955            StringBuilder buf = mStringBuilder;
2956            buf.setLength(0);
2957            buf.append("Start proc ");
2958            buf.append(app.processName);
2959            if (!isActivityProcess) {
2960                buf.append(" [");
2961                buf.append(entryPoint);
2962                buf.append("]");
2963            }
2964            buf.append(" for ");
2965            buf.append(hostingType);
2966            if (hostingNameStr != null) {
2967                buf.append(" ");
2968                buf.append(hostingNameStr);
2969            }
2970            buf.append(": pid=");
2971            buf.append(startResult.pid);
2972            buf.append(" uid=");
2973            buf.append(uid);
2974            buf.append(" gids={");
2975            if (gids != null) {
2976                for (int gi=0; gi<gids.length; gi++) {
2977                    if (gi != 0) buf.append(", ");
2978                    buf.append(gids[gi]);
2979
2980                }
2981            }
2982            buf.append("}");
2983            if (requiredAbi != null) {
2984                buf.append(" abi=");
2985                buf.append(requiredAbi);
2986            }
2987            Slog.i(TAG, buf.toString());
2988            app.setPid(startResult.pid);
2989            app.usingWrapper = startResult.usingWrapper;
2990            app.removed = false;
2991            app.killed = false;
2992            app.killedByAm = false;
2993            checkTime(startTime, "startProcess: starting to update pids map");
2994            synchronized (mPidsSelfLocked) {
2995                this.mPidsSelfLocked.put(startResult.pid, app);
2996                if (isActivityProcess) {
2997                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2998                    msg.obj = app;
2999                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3000                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3001                }
3002            }
3003            checkTime(startTime, "startProcess: done updating pids map");
3004        } catch (RuntimeException e) {
3005            // XXX do better error recovery.
3006            app.setPid(0);
3007            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3008            if (app.isolated) {
3009                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3010            }
3011            Slog.e(TAG, "Failure starting process " + app.processName, e);
3012        }
3013    }
3014
3015    void updateUsageStats(ActivityRecord component, boolean resumed) {
3016        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3017        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3018        if (resumed) {
3019            if (mUsageStatsService != null) {
3020                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3021                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3022            }
3023            synchronized (stats) {
3024                stats.noteActivityResumedLocked(component.app.uid);
3025            }
3026        } else {
3027            if (mUsageStatsService != null) {
3028                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3029                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3030            }
3031            synchronized (stats) {
3032                stats.noteActivityPausedLocked(component.app.uid);
3033            }
3034        }
3035    }
3036
3037    Intent getHomeIntent() {
3038        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3039        intent.setComponent(mTopComponent);
3040        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3041            intent.addCategory(Intent.CATEGORY_HOME);
3042        }
3043        return intent;
3044    }
3045
3046    boolean startHomeActivityLocked(int userId) {
3047        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3048                && mTopAction == null) {
3049            // We are running in factory test mode, but unable to find
3050            // the factory test app, so just sit around displaying the
3051            // error message and don't try to start anything.
3052            return false;
3053        }
3054        Intent intent = getHomeIntent();
3055        ActivityInfo aInfo =
3056            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3057        if (aInfo != null) {
3058            intent.setComponent(new ComponentName(
3059                    aInfo.applicationInfo.packageName, aInfo.name));
3060            // Don't do this if the home app is currently being
3061            // instrumented.
3062            aInfo = new ActivityInfo(aInfo);
3063            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3064            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3065                    aInfo.applicationInfo.uid, true);
3066            if (app == null || app.instrumentationClass == null) {
3067                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3068                mStackSupervisor.startHomeActivity(intent, aInfo);
3069            }
3070        }
3071
3072        return true;
3073    }
3074
3075    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3076        ActivityInfo ai = null;
3077        ComponentName comp = intent.getComponent();
3078        try {
3079            if (comp != null) {
3080                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3081            } else {
3082                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3083                        intent,
3084                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3085                            flags, userId);
3086
3087                if (info != null) {
3088                    ai = info.activityInfo;
3089                }
3090            }
3091        } catch (RemoteException e) {
3092            // ignore
3093        }
3094
3095        return ai;
3096    }
3097
3098    /**
3099     * Starts the "new version setup screen" if appropriate.
3100     */
3101    void startSetupActivityLocked() {
3102        // Only do this once per boot.
3103        if (mCheckedForSetup) {
3104            return;
3105        }
3106
3107        // We will show this screen if the current one is a different
3108        // version than the last one shown, and we are not running in
3109        // low-level factory test mode.
3110        final ContentResolver resolver = mContext.getContentResolver();
3111        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3112                Settings.Global.getInt(resolver,
3113                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3114            mCheckedForSetup = true;
3115
3116            // See if we should be showing the platform update setup UI.
3117            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3118            List<ResolveInfo> ris = mContext.getPackageManager()
3119                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3120
3121            // We don't allow third party apps to replace this.
3122            ResolveInfo ri = null;
3123            for (int i=0; ris != null && i<ris.size(); i++) {
3124                if ((ris.get(i).activityInfo.applicationInfo.flags
3125                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3126                    ri = ris.get(i);
3127                    break;
3128                }
3129            }
3130
3131            if (ri != null) {
3132                String vers = ri.activityInfo.metaData != null
3133                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3134                        : null;
3135                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3136                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3137                            Intent.METADATA_SETUP_VERSION);
3138                }
3139                String lastVers = Settings.Secure.getString(
3140                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3141                if (vers != null && !vers.equals(lastVers)) {
3142                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3143                    intent.setComponent(new ComponentName(
3144                            ri.activityInfo.packageName, ri.activityInfo.name));
3145                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3146                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3147                            null);
3148                }
3149            }
3150        }
3151    }
3152
3153    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3154        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3155    }
3156
3157    void enforceNotIsolatedCaller(String caller) {
3158        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3159            throw new SecurityException("Isolated process not allowed to call " + caller);
3160        }
3161    }
3162
3163    void enforceShellRestriction(String restriction, int userHandle) {
3164        if (Binder.getCallingUid() == Process.SHELL_UID) {
3165            if (userHandle < 0
3166                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3167                throw new SecurityException("Shell does not have permission to access user "
3168                        + userHandle);
3169            }
3170        }
3171    }
3172
3173    @Override
3174    public int getFrontActivityScreenCompatMode() {
3175        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3176        synchronized (this) {
3177            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3178        }
3179    }
3180
3181    @Override
3182    public void setFrontActivityScreenCompatMode(int mode) {
3183        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3184                "setFrontActivityScreenCompatMode");
3185        synchronized (this) {
3186            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3187        }
3188    }
3189
3190    @Override
3191    public int getPackageScreenCompatMode(String packageName) {
3192        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3193        synchronized (this) {
3194            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3195        }
3196    }
3197
3198    @Override
3199    public void setPackageScreenCompatMode(String packageName, int mode) {
3200        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3201                "setPackageScreenCompatMode");
3202        synchronized (this) {
3203            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3204        }
3205    }
3206
3207    @Override
3208    public boolean getPackageAskScreenCompat(String packageName) {
3209        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3210        synchronized (this) {
3211            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3212        }
3213    }
3214
3215    @Override
3216    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3217        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3218                "setPackageAskScreenCompat");
3219        synchronized (this) {
3220            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3221        }
3222    }
3223
3224    private void dispatchProcessesChanged() {
3225        int N;
3226        synchronized (this) {
3227            N = mPendingProcessChanges.size();
3228            if (mActiveProcessChanges.length < N) {
3229                mActiveProcessChanges = new ProcessChangeItem[N];
3230            }
3231            mPendingProcessChanges.toArray(mActiveProcessChanges);
3232            mAvailProcessChanges.addAll(mPendingProcessChanges);
3233            mPendingProcessChanges.clear();
3234            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3235        }
3236
3237        int i = mProcessObservers.beginBroadcast();
3238        while (i > 0) {
3239            i--;
3240            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3241            if (observer != null) {
3242                try {
3243                    for (int j=0; j<N; j++) {
3244                        ProcessChangeItem item = mActiveProcessChanges[j];
3245                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3246                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3247                                    + item.pid + " uid=" + item.uid + ": "
3248                                    + item.foregroundActivities);
3249                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3250                                    item.foregroundActivities);
3251                        }
3252                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3253                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3254                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3255                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3256                        }
3257                    }
3258                } catch (RemoteException e) {
3259                }
3260            }
3261        }
3262        mProcessObservers.finishBroadcast();
3263    }
3264
3265    private void dispatchProcessDied(int pid, int uid) {
3266        int i = mProcessObservers.beginBroadcast();
3267        while (i > 0) {
3268            i--;
3269            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3270            if (observer != null) {
3271                try {
3272                    observer.onProcessDied(pid, uid);
3273                } catch (RemoteException e) {
3274                }
3275            }
3276        }
3277        mProcessObservers.finishBroadcast();
3278    }
3279
3280    @Override
3281    public final int startActivity(IApplicationThread caller, String callingPackage,
3282            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3283            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3284        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3285            resultWho, requestCode, startFlags, profilerInfo, options,
3286            UserHandle.getCallingUserId());
3287    }
3288
3289    @Override
3290    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3291            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3292            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3293        enforceNotIsolatedCaller("startActivity");
3294        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3295                false, ALLOW_FULL_ONLY, "startActivity", null);
3296        // TODO: Switch to user app stacks here.
3297        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3298                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3299                profilerInfo, null, null, options, userId, null, null);
3300    }
3301
3302    @Override
3303    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3304            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3305            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3306
3307        // This is very dangerous -- it allows you to perform a start activity (including
3308        // permission grants) as any app that may launch one of your own activities.  So
3309        // we will only allow this to be done from activities that are part of the core framework,
3310        // and then only when they are running as the system.
3311        final ActivityRecord sourceRecord;
3312        final int targetUid;
3313        final String targetPackage;
3314        synchronized (this) {
3315            if (resultTo == null) {
3316                throw new SecurityException("Must be called from an activity");
3317            }
3318            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3319            if (sourceRecord == null) {
3320                throw new SecurityException("Called with bad activity token: " + resultTo);
3321            }
3322            if (!sourceRecord.info.packageName.equals("android")) {
3323                throw new SecurityException(
3324                        "Must be called from an activity that is declared in the android package");
3325            }
3326            if (sourceRecord.app == null) {
3327                throw new SecurityException("Called without a process attached to activity");
3328            }
3329            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3330                // This is still okay, as long as this activity is running under the
3331                // uid of the original calling activity.
3332                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3333                    throw new SecurityException(
3334                            "Calling activity in uid " + sourceRecord.app.uid
3335                                    + " must be system uid or original calling uid "
3336                                    + sourceRecord.launchedFromUid);
3337                }
3338            }
3339            targetUid = sourceRecord.launchedFromUid;
3340            targetPackage = sourceRecord.launchedFromPackage;
3341        }
3342
3343        if (userId == UserHandle.USER_NULL) {
3344            userId = UserHandle.getUserId(sourceRecord.app.uid);
3345        }
3346
3347        // TODO: Switch to user app stacks here.
3348        try {
3349            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3350                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3351                    null, null, options, userId, null, null);
3352            return ret;
3353        } catch (SecurityException e) {
3354            // XXX need to figure out how to propagate to original app.
3355            // A SecurityException here is generally actually a fault of the original
3356            // calling activity (such as a fairly granting permissions), so propagate it
3357            // back to them.
3358            /*
3359            StringBuilder msg = new StringBuilder();
3360            msg.append("While launching");
3361            msg.append(intent.toString());
3362            msg.append(": ");
3363            msg.append(e.getMessage());
3364            */
3365            throw e;
3366        }
3367    }
3368
3369    @Override
3370    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3371            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3372            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3373        enforceNotIsolatedCaller("startActivityAndWait");
3374        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3375                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3376        WaitResult res = new WaitResult();
3377        // TODO: Switch to user app stacks here.
3378        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3379                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3380                options, userId, null, null);
3381        return res;
3382    }
3383
3384    @Override
3385    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3386            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3387            int startFlags, Configuration config, Bundle options, int userId) {
3388        enforceNotIsolatedCaller("startActivityWithConfig");
3389        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3390                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3391        // TODO: Switch to user app stacks here.
3392        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3393                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3394                null, null, config, options, userId, null, null);
3395        return ret;
3396    }
3397
3398    @Override
3399    public int startActivityIntentSender(IApplicationThread caller,
3400            IntentSender intent, Intent fillInIntent, String resolvedType,
3401            IBinder resultTo, String resultWho, int requestCode,
3402            int flagsMask, int flagsValues, Bundle options) {
3403        enforceNotIsolatedCaller("startActivityIntentSender");
3404        // Refuse possible leaked file descriptors
3405        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3406            throw new IllegalArgumentException("File descriptors passed in Intent");
3407        }
3408
3409        IIntentSender sender = intent.getTarget();
3410        if (!(sender instanceof PendingIntentRecord)) {
3411            throw new IllegalArgumentException("Bad PendingIntent object");
3412        }
3413
3414        PendingIntentRecord pir = (PendingIntentRecord)sender;
3415
3416        synchronized (this) {
3417            // If this is coming from the currently resumed activity, it is
3418            // effectively saying that app switches are allowed at this point.
3419            final ActivityStack stack = getFocusedStack();
3420            if (stack.mResumedActivity != null &&
3421                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3422                mAppSwitchesAllowedTime = 0;
3423            }
3424        }
3425        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3426                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3427        return ret;
3428    }
3429
3430    @Override
3431    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3432            Intent intent, String resolvedType, IVoiceInteractionSession session,
3433            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3434            Bundle options, int userId) {
3435        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3436                != PackageManager.PERMISSION_GRANTED) {
3437            String msg = "Permission Denial: startVoiceActivity() from pid="
3438                    + Binder.getCallingPid()
3439                    + ", uid=" + Binder.getCallingUid()
3440                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3441            Slog.w(TAG, msg);
3442            throw new SecurityException(msg);
3443        }
3444        if (session == null || interactor == null) {
3445            throw new NullPointerException("null session or interactor");
3446        }
3447        userId = handleIncomingUser(callingPid, callingUid, userId,
3448                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3449        // TODO: Switch to user app stacks here.
3450        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3451                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3452                null, options, userId, null, null);
3453    }
3454
3455    @Override
3456    public boolean startNextMatchingActivity(IBinder callingActivity,
3457            Intent intent, Bundle options) {
3458        // Refuse possible leaked file descriptors
3459        if (intent != null && intent.hasFileDescriptors() == true) {
3460            throw new IllegalArgumentException("File descriptors passed in Intent");
3461        }
3462
3463        synchronized (this) {
3464            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3465            if (r == null) {
3466                ActivityOptions.abort(options);
3467                return false;
3468            }
3469            if (r.app == null || r.app.thread == null) {
3470                // The caller is not running...  d'oh!
3471                ActivityOptions.abort(options);
3472                return false;
3473            }
3474            intent = new Intent(intent);
3475            // The caller is not allowed to change the data.
3476            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3477            // And we are resetting to find the next component...
3478            intent.setComponent(null);
3479
3480            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3481
3482            ActivityInfo aInfo = null;
3483            try {
3484                List<ResolveInfo> resolves =
3485                    AppGlobals.getPackageManager().queryIntentActivities(
3486                            intent, r.resolvedType,
3487                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3488                            UserHandle.getCallingUserId());
3489
3490                // Look for the original activity in the list...
3491                final int N = resolves != null ? resolves.size() : 0;
3492                for (int i=0; i<N; i++) {
3493                    ResolveInfo rInfo = resolves.get(i);
3494                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3495                            && rInfo.activityInfo.name.equals(r.info.name)) {
3496                        // We found the current one...  the next matching is
3497                        // after it.
3498                        i++;
3499                        if (i<N) {
3500                            aInfo = resolves.get(i).activityInfo;
3501                        }
3502                        if (debug) {
3503                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3504                                    + "/" + r.info.name);
3505                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3506                                    + "/" + aInfo.name);
3507                        }
3508                        break;
3509                    }
3510                }
3511            } catch (RemoteException e) {
3512            }
3513
3514            if (aInfo == null) {
3515                // Nobody who is next!
3516                ActivityOptions.abort(options);
3517                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3518                return false;
3519            }
3520
3521            intent.setComponent(new ComponentName(
3522                    aInfo.applicationInfo.packageName, aInfo.name));
3523            intent.setFlags(intent.getFlags()&~(
3524                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3525                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3526                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3527                    Intent.FLAG_ACTIVITY_NEW_TASK));
3528
3529            // Okay now we need to start the new activity, replacing the
3530            // currently running activity.  This is a little tricky because
3531            // we want to start the new one as if the current one is finished,
3532            // but not finish the current one first so that there is no flicker.
3533            // And thus...
3534            final boolean wasFinishing = r.finishing;
3535            r.finishing = true;
3536
3537            // Propagate reply information over to the new activity.
3538            final ActivityRecord resultTo = r.resultTo;
3539            final String resultWho = r.resultWho;
3540            final int requestCode = r.requestCode;
3541            r.resultTo = null;
3542            if (resultTo != null) {
3543                resultTo.removeResultsLocked(r, resultWho, requestCode);
3544            }
3545
3546            final long origId = Binder.clearCallingIdentity();
3547            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3548                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3549                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3550                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3551            Binder.restoreCallingIdentity(origId);
3552
3553            r.finishing = wasFinishing;
3554            if (res != ActivityManager.START_SUCCESS) {
3555                return false;
3556            }
3557            return true;
3558        }
3559    }
3560
3561    @Override
3562    public final int startActivityFromRecents(int taskId, Bundle options) {
3563        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3564            String msg = "Permission Denial: startActivityFromRecents called without " +
3565                    START_TASKS_FROM_RECENTS;
3566            Slog.w(TAG, msg);
3567            throw new SecurityException(msg);
3568        }
3569        return startActivityFromRecentsInner(taskId, options);
3570    }
3571
3572    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3573        final TaskRecord task;
3574        final int callingUid;
3575        final String callingPackage;
3576        final Intent intent;
3577        final int userId;
3578        synchronized (this) {
3579            task = recentTaskForIdLocked(taskId);
3580            if (task == null) {
3581                throw new IllegalArgumentException("Task " + taskId + " not found.");
3582            }
3583            callingUid = task.mCallingUid;
3584            callingPackage = task.mCallingPackage;
3585            intent = task.intent;
3586            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3587            userId = task.userId;
3588        }
3589        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3590                options, userId, null, task);
3591    }
3592
3593    final int startActivityInPackage(int uid, String callingPackage,
3594            Intent intent, String resolvedType, IBinder resultTo,
3595            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3596            IActivityContainer container, TaskRecord inTask) {
3597
3598        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3599                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3600
3601        // TODO: Switch to user app stacks here.
3602        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3603                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3604                null, null, null, options, userId, container, inTask);
3605        return ret;
3606    }
3607
3608    @Override
3609    public final int startActivities(IApplicationThread caller, String callingPackage,
3610            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3611            int userId) {
3612        enforceNotIsolatedCaller("startActivities");
3613        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3614                false, ALLOW_FULL_ONLY, "startActivity", null);
3615        // TODO: Switch to user app stacks here.
3616        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3617                resolvedTypes, resultTo, options, userId);
3618        return ret;
3619    }
3620
3621    final int startActivitiesInPackage(int uid, String callingPackage,
3622            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3623            Bundle options, int userId) {
3624
3625        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3626                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3627        // TODO: Switch to user app stacks here.
3628        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3629                resultTo, options, userId);
3630        return ret;
3631    }
3632
3633    //explicitly remove thd old information in mRecentTasks when removing existing user.
3634    private void removeRecentTasksForUserLocked(int userId) {
3635        if(userId <= 0) {
3636            Slog.i(TAG, "Can't remove recent task on user " + userId);
3637            return;
3638        }
3639
3640        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3641            TaskRecord tr = mRecentTasks.get(i);
3642            if (tr.userId == userId) {
3643                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3644                        + " when finishing user" + userId);
3645                mRecentTasks.remove(i);
3646                tr.removedFromRecents(mTaskPersister);
3647            }
3648        }
3649
3650        // Remove tasks from persistent storage.
3651        mTaskPersister.wakeup(null, true);
3652    }
3653
3654    // Sort by taskId
3655    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3656        @Override
3657        public int compare(TaskRecord lhs, TaskRecord rhs) {
3658            return rhs.taskId - lhs.taskId;
3659        }
3660    };
3661
3662    // Extract the affiliates of the chain containing mRecentTasks[start].
3663    private int processNextAffiliateChain(int start) {
3664        final TaskRecord startTask = mRecentTasks.get(start);
3665        final int affiliateId = startTask.mAffiliatedTaskId;
3666
3667        // Quick identification of isolated tasks. I.e. those not launched behind.
3668        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3669                startTask.mNextAffiliate == null) {
3670            // There is still a slim chance that there are other tasks that point to this task
3671            // and that the chain is so messed up that this task no longer points to them but
3672            // the gain of this optimization outweighs the risk.
3673            startTask.inRecents = true;
3674            return start + 1;
3675        }
3676
3677        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3678        mTmpRecents.clear();
3679        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3680            final TaskRecord task = mRecentTasks.get(i);
3681            if (task.mAffiliatedTaskId == affiliateId) {
3682                mRecentTasks.remove(i);
3683                mTmpRecents.add(task);
3684            }
3685        }
3686
3687        // Sort them all by taskId. That is the order they were create in and that order will
3688        // always be correct.
3689        Collections.sort(mTmpRecents, mTaskRecordComparator);
3690
3691        // Go through and fix up the linked list.
3692        // The first one is the end of the chain and has no next.
3693        final TaskRecord first = mTmpRecents.get(0);
3694        first.inRecents = true;
3695        if (first.mNextAffiliate != null) {
3696            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3697            first.setNextAffiliate(null);
3698            mTaskPersister.wakeup(first, false);
3699        }
3700        // Everything in the middle is doubly linked from next to prev.
3701        final int tmpSize = mTmpRecents.size();
3702        for (int i = 0; i < tmpSize - 1; ++i) {
3703            final TaskRecord next = mTmpRecents.get(i);
3704            final TaskRecord prev = mTmpRecents.get(i + 1);
3705            if (next.mPrevAffiliate != prev) {
3706                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3707                        " setting prev=" + prev);
3708                next.setPrevAffiliate(prev);
3709                mTaskPersister.wakeup(next, false);
3710            }
3711            if (prev.mNextAffiliate != next) {
3712                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3713                        " setting next=" + next);
3714                prev.setNextAffiliate(next);
3715                mTaskPersister.wakeup(prev, false);
3716            }
3717            prev.inRecents = true;
3718        }
3719        // The last one is the beginning of the list and has no prev.
3720        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3721        if (last.mPrevAffiliate != null) {
3722            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3723            last.setPrevAffiliate(null);
3724            mTaskPersister.wakeup(last, false);
3725        }
3726
3727        // Insert the group back into mRecentTasks at start.
3728        mRecentTasks.addAll(start, mTmpRecents);
3729
3730        // Let the caller know where we left off.
3731        return start + tmpSize;
3732    }
3733
3734    /**
3735     * Update the recent tasks lists: make sure tasks should still be here (their
3736     * applications / activities still exist), update their availability, fixup ordering
3737     * of affiliations.
3738     */
3739    void cleanupRecentTasksLocked(int userId) {
3740        if (mRecentTasks == null) {
3741            // Happens when called from the packagemanager broadcast before boot.
3742            return;
3743        }
3744
3745        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3746        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3747        final IPackageManager pm = AppGlobals.getPackageManager();
3748        final ActivityInfo dummyAct = new ActivityInfo();
3749        final ApplicationInfo dummyApp = new ApplicationInfo();
3750
3751        int N = mRecentTasks.size();
3752
3753        int[] users = userId == UserHandle.USER_ALL
3754                ? getUsersLocked() : new int[] { userId };
3755        for (int user : users) {
3756            for (int i = 0; i < N; i++) {
3757                TaskRecord task = mRecentTasks.get(i);
3758                if (task.userId != user) {
3759                    // Only look at tasks for the user ID of interest.
3760                    continue;
3761                }
3762                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3763                    // This situation is broken, and we should just get rid of it now.
3764                    mRecentTasks.remove(i);
3765                    task.removedFromRecents(mTaskPersister);
3766                    i--;
3767                    N--;
3768                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3769                    continue;
3770                }
3771                // Check whether this activity is currently available.
3772                if (task.realActivity != null) {
3773                    ActivityInfo ai = availActCache.get(task.realActivity);
3774                    if (ai == null) {
3775                        try {
3776                            ai = pm.getActivityInfo(task.realActivity,
3777                                    PackageManager.GET_UNINSTALLED_PACKAGES
3778                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3779                        } catch (RemoteException e) {
3780                            // Will never happen.
3781                            continue;
3782                        }
3783                        if (ai == null) {
3784                            ai = dummyAct;
3785                        }
3786                        availActCache.put(task.realActivity, ai);
3787                    }
3788                    if (ai == dummyAct) {
3789                        // This could be either because the activity no longer exists, or the
3790                        // app is temporarily gone.  For the former we want to remove the recents
3791                        // entry; for the latter we want to mark it as unavailable.
3792                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3793                        if (app == null) {
3794                            try {
3795                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3796                                        PackageManager.GET_UNINSTALLED_PACKAGES
3797                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3798                            } catch (RemoteException e) {
3799                                // Will never happen.
3800                                continue;
3801                            }
3802                            if (app == null) {
3803                                app = dummyApp;
3804                            }
3805                            availAppCache.put(task.realActivity.getPackageName(), app);
3806                        }
3807                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3808                            // Doesn't exist any more!  Good-bye.
3809                            mRecentTasks.remove(i);
3810                            task.removedFromRecents(mTaskPersister);
3811                            i--;
3812                            N--;
3813                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3814                            continue;
3815                        } else {
3816                            // Otherwise just not available for now.
3817                            if (task.isAvailable) {
3818                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3819                                        + task);
3820                            }
3821                            task.isAvailable = false;
3822                        }
3823                    } else {
3824                        if (!ai.enabled || !ai.applicationInfo.enabled
3825                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3826                            if (task.isAvailable) {
3827                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3828                                        + task + " (enabled=" + ai.enabled + "/"
3829                                        + ai.applicationInfo.enabled +  " flags="
3830                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3831                            }
3832                            task.isAvailable = false;
3833                        } else {
3834                            if (!task.isAvailable) {
3835                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3836                                        + task);
3837                            }
3838                            task.isAvailable = true;
3839                        }
3840                    }
3841                }
3842            }
3843        }
3844
3845        // Verify the affiliate chain for each task.
3846        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
3847        }
3848
3849        mTmpRecents.clear();
3850        // mRecentTasks is now in sorted, affiliated order.
3851    }
3852
3853    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3854        int N = mRecentTasks.size();
3855        TaskRecord top = task;
3856        int topIndex = taskIndex;
3857        while (top.mNextAffiliate != null && topIndex > 0) {
3858            top = top.mNextAffiliate;
3859            topIndex--;
3860        }
3861        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3862                + topIndex + " from intial " + taskIndex);
3863        // Find the end of the chain, doing a sanity check along the way.
3864        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3865        int endIndex = topIndex;
3866        TaskRecord prev = top;
3867        while (endIndex < N) {
3868            TaskRecord cur = mRecentTasks.get(endIndex);
3869            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3870                    + endIndex + " " + cur);
3871            if (cur == top) {
3872                // Verify start of the chain.
3873                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3874                    Slog.wtf(TAG, "Bad chain @" + endIndex
3875                            + ": first task has next affiliate: " + prev);
3876                    sane = false;
3877                    break;
3878                }
3879            } else {
3880                // Verify middle of the chain's next points back to the one before.
3881                if (cur.mNextAffiliate != prev
3882                        || cur.mNextAffiliateTaskId != prev.taskId) {
3883                    Slog.wtf(TAG, "Bad chain @" + endIndex
3884                            + ": middle task " + cur + " @" + endIndex
3885                            + " has bad next affiliate "
3886                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3887                            + ", expected " + prev);
3888                    sane = false;
3889                    break;
3890                }
3891            }
3892            if (cur.mPrevAffiliateTaskId == -1) {
3893                // Chain ends here.
3894                if (cur.mPrevAffiliate != null) {
3895                    Slog.wtf(TAG, "Bad chain @" + endIndex
3896                            + ": last task " + cur + " has previous affiliate "
3897                            + cur.mPrevAffiliate);
3898                    sane = false;
3899                }
3900                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3901                break;
3902            } else {
3903                // Verify middle of the chain's prev points to a valid item.
3904                if (cur.mPrevAffiliate == null) {
3905                    Slog.wtf(TAG, "Bad chain @" + endIndex
3906                            + ": task " + cur + " has previous affiliate "
3907                            + cur.mPrevAffiliate + " but should be id "
3908                            + cur.mPrevAffiliate);
3909                    sane = false;
3910                    break;
3911                }
3912            }
3913            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3914                Slog.wtf(TAG, "Bad chain @" + endIndex
3915                        + ": task " + cur + " has affiliated id "
3916                        + cur.mAffiliatedTaskId + " but should be "
3917                        + task.mAffiliatedTaskId);
3918                sane = false;
3919                break;
3920            }
3921            prev = cur;
3922            endIndex++;
3923            if (endIndex >= N) {
3924                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3925                        + ": last task " + prev);
3926                sane = false;
3927                break;
3928            }
3929        }
3930        if (sane) {
3931            if (endIndex < taskIndex) {
3932                Slog.wtf(TAG, "Bad chain @" + endIndex
3933                        + ": did not extend to task " + task + " @" + taskIndex);
3934                sane = false;
3935            }
3936        }
3937        if (sane) {
3938            // All looks good, we can just move all of the affiliated tasks
3939            // to the top.
3940            for (int i=topIndex; i<=endIndex; i++) {
3941                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3942                        + " from " + i + " to " + (i-topIndex));
3943                TaskRecord cur = mRecentTasks.remove(i);
3944                mRecentTasks.add(i-topIndex, cur);
3945            }
3946            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3947                    + " to " + endIndex);
3948            return true;
3949        }
3950
3951        // Whoops, couldn't do it.
3952        return false;
3953    }
3954
3955    final void addRecentTaskLocked(TaskRecord task) {
3956        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
3957                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
3958
3959        int N = mRecentTasks.size();
3960        // Quick case: check if the top-most recent task is the same.
3961        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
3962            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
3963            return;
3964        }
3965        // Another quick case: check if this is part of a set of affiliated
3966        // tasks that are at the top.
3967        if (isAffiliated && N > 0 && task.inRecents
3968                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
3969            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
3970                    + " at top when adding " + task);
3971            return;
3972        }
3973        // Another quick case: never add voice sessions.
3974        if (task.voiceSession != null) {
3975            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
3976            return;
3977        }
3978
3979        boolean needAffiliationFix = false;
3980
3981        // Slightly less quick case: the task is already in recents, so all we need
3982        // to do is move it.
3983        if (task.inRecents) {
3984            int taskIndex = mRecentTasks.indexOf(task);
3985            if (taskIndex >= 0) {
3986                if (!isAffiliated) {
3987                    // Simple case: this is not an affiliated task, so we just move it to the front.
3988                    mRecentTasks.remove(taskIndex);
3989                    mRecentTasks.add(0, task);
3990                    notifyTaskPersisterLocked(task, false);
3991                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
3992                            + " from " + taskIndex);
3993                    return;
3994                } else {
3995                    // More complicated: need to keep all affiliated tasks together.
3996                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
3997                        // All went well.
3998                        return;
3999                    }
4000
4001                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4002                    // everything and then go through our general path of adding a new task.
4003                    needAffiliationFix = true;
4004                }
4005            } else {
4006                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4007                needAffiliationFix = true;
4008            }
4009        }
4010
4011        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4012        trimRecentsForTask(task, true);
4013
4014        N = mRecentTasks.size();
4015        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4016            final TaskRecord tr = mRecentTasks.remove(N - 1);
4017            tr.removedFromRecents(mTaskPersister);
4018            N--;
4019        }
4020        task.inRecents = true;
4021        if (!isAffiliated || needAffiliationFix) {
4022            // If this is a simple non-affiliated task, or we had some failure trying to
4023            // handle it as part of an affilated task, then just place it at the top.
4024            mRecentTasks.add(0, task);
4025        } else if (isAffiliated) {
4026            // If this is a new affiliated task, then move all of the affiliated tasks
4027            // to the front and insert this new one.
4028            TaskRecord other = task.mNextAffiliate;
4029            if (other == null) {
4030                other = task.mPrevAffiliate;
4031            }
4032            if (other != null) {
4033                int otherIndex = mRecentTasks.indexOf(other);
4034                if (otherIndex >= 0) {
4035                    // Insert new task at appropriate location.
4036                    int taskIndex;
4037                    if (other == task.mNextAffiliate) {
4038                        // We found the index of our next affiliation, which is who is
4039                        // before us in the list, so add after that point.
4040                        taskIndex = otherIndex+1;
4041                    } else {
4042                        // We found the index of our previous affiliation, which is who is
4043                        // after us in the list, so add at their position.
4044                        taskIndex = otherIndex;
4045                    }
4046                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4047                            + taskIndex + ": " + task);
4048                    mRecentTasks.add(taskIndex, task);
4049
4050                    // Now move everything to the front.
4051                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4052                        // All went well.
4053                        return;
4054                    }
4055
4056                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4057                    // everything and then go through our general path of adding a new task.
4058                    needAffiliationFix = true;
4059                } else {
4060                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4061                            + other);
4062                    needAffiliationFix = true;
4063                }
4064            } else {
4065                if (DEBUG_RECENTS) Slog.d(TAG,
4066                        "addRecent: adding affiliated task without next/prev:" + task);
4067                needAffiliationFix = true;
4068            }
4069        }
4070        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4071
4072        if (needAffiliationFix) {
4073            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4074            cleanupRecentTasksLocked(task.userId);
4075        }
4076    }
4077
4078    /**
4079     * If needed, remove oldest existing entries in recents that are for the same kind
4080     * of task as the given one.
4081     */
4082    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4083        int N = mRecentTasks.size();
4084        final Intent intent = task.intent;
4085        final boolean document = intent != null && intent.isDocument();
4086
4087        int maxRecents = task.maxRecents - 1;
4088        for (int i=0; i<N; i++) {
4089            final TaskRecord tr = mRecentTasks.get(i);
4090            if (task != tr) {
4091                if (task.userId != tr.userId) {
4092                    continue;
4093                }
4094                if (i > MAX_RECENT_BITMAPS) {
4095                    tr.freeLastThumbnail();
4096                }
4097                final Intent trIntent = tr.intent;
4098                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4099                    (intent == null || !intent.filterEquals(trIntent))) {
4100                    continue;
4101                }
4102                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4103                if (document && trIsDocument) {
4104                    // These are the same document activity (not necessarily the same doc).
4105                    if (maxRecents > 0) {
4106                        --maxRecents;
4107                        continue;
4108                    }
4109                    // Hit the maximum number of documents for this task. Fall through
4110                    // and remove this document from recents.
4111                } else if (document || trIsDocument) {
4112                    // Only one of these is a document. Not the droid we're looking for.
4113                    continue;
4114                }
4115            }
4116
4117            if (!doTrim) {
4118                // If the caller is not actually asking for a trim, just tell them we reached
4119                // a point where the trim would happen.
4120                return i;
4121            }
4122
4123            // Either task and tr are the same or, their affinities match or their intents match
4124            // and neither of them is a document, or they are documents using the same activity
4125            // and their maxRecents has been reached.
4126            tr.disposeThumbnail();
4127            mRecentTasks.remove(i);
4128            if (task != tr) {
4129                tr.removedFromRecents(mTaskPersister);
4130            }
4131            i--;
4132            N--;
4133            if (task.intent == null) {
4134                // If the new recent task we are adding is not fully
4135                // specified, then replace it with the existing recent task.
4136                task = tr;
4137            }
4138            notifyTaskPersisterLocked(tr, false);
4139        }
4140
4141        return -1;
4142    }
4143
4144    @Override
4145    public void reportActivityFullyDrawn(IBinder token) {
4146        synchronized (this) {
4147            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4148            if (r == null) {
4149                return;
4150            }
4151            r.reportFullyDrawnLocked();
4152        }
4153    }
4154
4155    @Override
4156    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4157        synchronized (this) {
4158            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4159            if (r == null) {
4160                return;
4161            }
4162            final long origId = Binder.clearCallingIdentity();
4163            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4164            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4165                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4166            if (config != null) {
4167                r.frozenBeforeDestroy = true;
4168                if (!updateConfigurationLocked(config, r, false, false)) {
4169                    mStackSupervisor.resumeTopActivitiesLocked();
4170                }
4171            }
4172            Binder.restoreCallingIdentity(origId);
4173        }
4174    }
4175
4176    @Override
4177    public int getRequestedOrientation(IBinder token) {
4178        synchronized (this) {
4179            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4180            if (r == null) {
4181                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4182            }
4183            return mWindowManager.getAppOrientation(r.appToken);
4184        }
4185    }
4186
4187    /**
4188     * This is the internal entry point for handling Activity.finish().
4189     *
4190     * @param token The Binder token referencing the Activity we want to finish.
4191     * @param resultCode Result code, if any, from this Activity.
4192     * @param resultData Result data (Intent), if any, from this Activity.
4193     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4194     *            the root Activity in the task.
4195     *
4196     * @return Returns true if the activity successfully finished, or false if it is still running.
4197     */
4198    @Override
4199    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4200            boolean finishTask) {
4201        // Refuse possible leaked file descriptors
4202        if (resultData != null && resultData.hasFileDescriptors() == true) {
4203            throw new IllegalArgumentException("File descriptors passed in Intent");
4204        }
4205
4206        synchronized(this) {
4207            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4208            if (r == null) {
4209                return true;
4210            }
4211            // Keep track of the root activity of the task before we finish it
4212            TaskRecord tr = r.task;
4213            ActivityRecord rootR = tr.getRootActivity();
4214            if (rootR == null) {
4215                Slog.w(TAG, "Finishing task with all activities already finished");
4216            }
4217            // Do not allow task to finish in Lock Task mode.
4218            if (tr == mStackSupervisor.mLockTaskModeTask) {
4219                if (rootR == r) {
4220                    Slog.i(TAG, "Not finishing task in lock task mode");
4221                    mStackSupervisor.showLockTaskToast();
4222                    return false;
4223                }
4224            }
4225            if (mController != null) {
4226                // Find the first activity that is not finishing.
4227                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4228                if (next != null) {
4229                    // ask watcher if this is allowed
4230                    boolean resumeOK = true;
4231                    try {
4232                        resumeOK = mController.activityResuming(next.packageName);
4233                    } catch (RemoteException e) {
4234                        mController = null;
4235                        Watchdog.getInstance().setActivityController(null);
4236                    }
4237
4238                    if (!resumeOK) {
4239                        Slog.i(TAG, "Not finishing activity because controller resumed");
4240                        return false;
4241                    }
4242                }
4243            }
4244            final long origId = Binder.clearCallingIdentity();
4245            try {
4246                boolean res;
4247                if (finishTask && r == rootR) {
4248                    // If requested, remove the task that is associated to this activity only if it
4249                    // was the root activity in the task. The result code and data is ignored
4250                    // because we don't support returning them across task boundaries.
4251                    res = removeTaskByIdLocked(tr.taskId, false);
4252                    if (!res) {
4253                        Slog.i(TAG, "Removing task failed to finish activity");
4254                    }
4255                } else {
4256                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4257                            resultData, "app-request", true);
4258                    if (!res) {
4259                        Slog.i(TAG, "Failed to finish by app-request");
4260                    }
4261                }
4262                return res;
4263            } finally {
4264                Binder.restoreCallingIdentity(origId);
4265            }
4266        }
4267    }
4268
4269    @Override
4270    public final void finishHeavyWeightApp() {
4271        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4272                != PackageManager.PERMISSION_GRANTED) {
4273            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4274                    + Binder.getCallingPid()
4275                    + ", uid=" + Binder.getCallingUid()
4276                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4277            Slog.w(TAG, msg);
4278            throw new SecurityException(msg);
4279        }
4280
4281        synchronized(this) {
4282            if (mHeavyWeightProcess == null) {
4283                return;
4284            }
4285
4286            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4287                    mHeavyWeightProcess.activities);
4288            for (int i=0; i<activities.size(); i++) {
4289                ActivityRecord r = activities.get(i);
4290                if (!r.finishing) {
4291                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4292                            null, "finish-heavy", true);
4293                }
4294            }
4295
4296            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4297                    mHeavyWeightProcess.userId, 0));
4298            mHeavyWeightProcess = null;
4299        }
4300    }
4301
4302    @Override
4303    public void crashApplication(int uid, int initialPid, String packageName,
4304            String message) {
4305        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4306                != PackageManager.PERMISSION_GRANTED) {
4307            String msg = "Permission Denial: crashApplication() from pid="
4308                    + Binder.getCallingPid()
4309                    + ", uid=" + Binder.getCallingUid()
4310                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4311            Slog.w(TAG, msg);
4312            throw new SecurityException(msg);
4313        }
4314
4315        synchronized(this) {
4316            ProcessRecord proc = null;
4317
4318            // Figure out which process to kill.  We don't trust that initialPid
4319            // still has any relation to current pids, so must scan through the
4320            // list.
4321            synchronized (mPidsSelfLocked) {
4322                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4323                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4324                    if (p.uid != uid) {
4325                        continue;
4326                    }
4327                    if (p.pid == initialPid) {
4328                        proc = p;
4329                        break;
4330                    }
4331                    if (p.pkgList.containsKey(packageName)) {
4332                        proc = p;
4333                    }
4334                }
4335            }
4336
4337            if (proc == null) {
4338                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4339                        + " initialPid=" + initialPid
4340                        + " packageName=" + packageName);
4341                return;
4342            }
4343
4344            if (proc.thread != null) {
4345                if (proc.pid == Process.myPid()) {
4346                    Log.w(TAG, "crashApplication: trying to crash self!");
4347                    return;
4348                }
4349                long ident = Binder.clearCallingIdentity();
4350                try {
4351                    proc.thread.scheduleCrash(message);
4352                } catch (RemoteException e) {
4353                }
4354                Binder.restoreCallingIdentity(ident);
4355            }
4356        }
4357    }
4358
4359    @Override
4360    public final void finishSubActivity(IBinder token, String resultWho,
4361            int requestCode) {
4362        synchronized(this) {
4363            final long origId = Binder.clearCallingIdentity();
4364            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4365            if (r != null) {
4366                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4367            }
4368            Binder.restoreCallingIdentity(origId);
4369        }
4370    }
4371
4372    @Override
4373    public boolean finishActivityAffinity(IBinder token) {
4374        synchronized(this) {
4375            final long origId = Binder.clearCallingIdentity();
4376            try {
4377                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4378
4379                ActivityRecord rootR = r.task.getRootActivity();
4380                // Do not allow task to finish in Lock Task mode.
4381                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4382                    if (rootR == r) {
4383                        mStackSupervisor.showLockTaskToast();
4384                        return false;
4385                    }
4386                }
4387                boolean res = false;
4388                if (r != null) {
4389                    res = r.task.stack.finishActivityAffinityLocked(r);
4390                }
4391                return res;
4392            } finally {
4393                Binder.restoreCallingIdentity(origId);
4394            }
4395        }
4396    }
4397
4398    @Override
4399    public void finishVoiceTask(IVoiceInteractionSession session) {
4400        synchronized(this) {
4401            final long origId = Binder.clearCallingIdentity();
4402            try {
4403                mStackSupervisor.finishVoiceTask(session);
4404            } finally {
4405                Binder.restoreCallingIdentity(origId);
4406            }
4407        }
4408
4409    }
4410
4411    @Override
4412    public boolean releaseActivityInstance(IBinder token) {
4413        synchronized(this) {
4414            final long origId = Binder.clearCallingIdentity();
4415            try {
4416                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4417                if (r.task == null || r.task.stack == null) {
4418                    return false;
4419                }
4420                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4421            } finally {
4422                Binder.restoreCallingIdentity(origId);
4423            }
4424        }
4425    }
4426
4427    @Override
4428    public void releaseSomeActivities(IApplicationThread appInt) {
4429        synchronized(this) {
4430            final long origId = Binder.clearCallingIdentity();
4431            try {
4432                ProcessRecord app = getRecordForAppLocked(appInt);
4433                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4434            } finally {
4435                Binder.restoreCallingIdentity(origId);
4436            }
4437        }
4438    }
4439
4440    @Override
4441    public boolean willActivityBeVisible(IBinder token) {
4442        synchronized(this) {
4443            ActivityStack stack = ActivityRecord.getStackLocked(token);
4444            if (stack != null) {
4445                return stack.willActivityBeVisibleLocked(token);
4446            }
4447            return false;
4448        }
4449    }
4450
4451    @Override
4452    public void overridePendingTransition(IBinder token, String packageName,
4453            int enterAnim, int exitAnim) {
4454        synchronized(this) {
4455            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4456            if (self == null) {
4457                return;
4458            }
4459
4460            final long origId = Binder.clearCallingIdentity();
4461
4462            if (self.state == ActivityState.RESUMED
4463                    || self.state == ActivityState.PAUSING) {
4464                mWindowManager.overridePendingAppTransition(packageName,
4465                        enterAnim, exitAnim, null);
4466            }
4467
4468            Binder.restoreCallingIdentity(origId);
4469        }
4470    }
4471
4472    /**
4473     * Main function for removing an existing process from the activity manager
4474     * as a result of that process going away.  Clears out all connections
4475     * to the process.
4476     */
4477    private final void handleAppDiedLocked(ProcessRecord app,
4478            boolean restarting, boolean allowRestart) {
4479        int pid = app.pid;
4480        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4481        if (!kept && !restarting) {
4482            removeLruProcessLocked(app);
4483            if (pid > 0) {
4484                ProcessList.remove(pid);
4485            }
4486        }
4487
4488        if (mProfileProc == app) {
4489            clearProfilerLocked();
4490        }
4491
4492        // Remove this application's activities from active lists.
4493        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4494
4495        app.activities.clear();
4496
4497        if (app.instrumentationClass != null) {
4498            Slog.w(TAG, "Crash of app " + app.processName
4499                  + " running instrumentation " + app.instrumentationClass);
4500            Bundle info = new Bundle();
4501            info.putString("shortMsg", "Process crashed.");
4502            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4503        }
4504
4505        if (!restarting) {
4506            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4507                // If there was nothing to resume, and we are not already
4508                // restarting this process, but there is a visible activity that
4509                // is hosted by the process...  then make sure all visible
4510                // activities are running, taking care of restarting this
4511                // process.
4512                if (hasVisibleActivities) {
4513                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4514                }
4515            }
4516        }
4517    }
4518
4519    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4520        IBinder threadBinder = thread.asBinder();
4521        // Find the application record.
4522        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4523            ProcessRecord rec = mLruProcesses.get(i);
4524            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4525                return i;
4526            }
4527        }
4528        return -1;
4529    }
4530
4531    final ProcessRecord getRecordForAppLocked(
4532            IApplicationThread thread) {
4533        if (thread == null) {
4534            return null;
4535        }
4536
4537        int appIndex = getLRURecordIndexForAppLocked(thread);
4538        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4539    }
4540
4541    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4542        // If there are no longer any background processes running,
4543        // and the app that died was not running instrumentation,
4544        // then tell everyone we are now low on memory.
4545        boolean haveBg = false;
4546        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4547            ProcessRecord rec = mLruProcesses.get(i);
4548            if (rec.thread != null
4549                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4550                haveBg = true;
4551                break;
4552            }
4553        }
4554
4555        if (!haveBg) {
4556            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4557            if (doReport) {
4558                long now = SystemClock.uptimeMillis();
4559                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4560                    doReport = false;
4561                } else {
4562                    mLastMemUsageReportTime = now;
4563                }
4564            }
4565            final ArrayList<ProcessMemInfo> memInfos
4566                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4567            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4568            long now = SystemClock.uptimeMillis();
4569            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4570                ProcessRecord rec = mLruProcesses.get(i);
4571                if (rec == dyingProc || rec.thread == null) {
4572                    continue;
4573                }
4574                if (doReport) {
4575                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4576                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4577                }
4578                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4579                    // The low memory report is overriding any current
4580                    // state for a GC request.  Make sure to do
4581                    // heavy/important/visible/foreground processes first.
4582                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4583                        rec.lastRequestedGc = 0;
4584                    } else {
4585                        rec.lastRequestedGc = rec.lastLowMemory;
4586                    }
4587                    rec.reportLowMemory = true;
4588                    rec.lastLowMemory = now;
4589                    mProcessesToGc.remove(rec);
4590                    addProcessToGcListLocked(rec);
4591                }
4592            }
4593            if (doReport) {
4594                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4595                mHandler.sendMessage(msg);
4596            }
4597            scheduleAppGcsLocked();
4598        }
4599    }
4600
4601    final void appDiedLocked(ProcessRecord app) {
4602       appDiedLocked(app, app.pid, app.thread);
4603    }
4604
4605    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4606        // First check if this ProcessRecord is actually active for the pid.
4607        synchronized (mPidsSelfLocked) {
4608            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4609            if (curProc != app) {
4610                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4611                return;
4612            }
4613        }
4614
4615        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4616        synchronized (stats) {
4617            stats.noteProcessDiedLocked(app.info.uid, pid);
4618        }
4619
4620        Process.killProcessQuiet(pid);
4621        Process.killProcessGroup(app.info.uid, pid);
4622        app.killed = true;
4623
4624        // Clean up already done if the process has been re-started.
4625        if (app.pid == pid && app.thread != null &&
4626                app.thread.asBinder() == thread.asBinder()) {
4627            boolean doLowMem = app.instrumentationClass == null;
4628            boolean doOomAdj = doLowMem;
4629            if (!app.killedByAm) {
4630                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4631                        + ") has died");
4632                mAllowLowerMemLevel = true;
4633            } else {
4634                // Note that we always want to do oom adj to update our state with the
4635                // new number of procs.
4636                mAllowLowerMemLevel = false;
4637                doLowMem = false;
4638            }
4639            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4640            if (DEBUG_CLEANUP) Slog.v(
4641                TAG, "Dying app: " + app + ", pid: " + pid
4642                + ", thread: " + thread.asBinder());
4643            handleAppDiedLocked(app, false, true);
4644
4645            if (doOomAdj) {
4646                updateOomAdjLocked();
4647            }
4648            if (doLowMem) {
4649                doLowMemReportIfNeededLocked(app);
4650            }
4651        } else if (app.pid != pid) {
4652            // A new process has already been started.
4653            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4654                    + ") has died and restarted (pid " + app.pid + ").");
4655            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4656        } else if (DEBUG_PROCESSES) {
4657            Slog.d(TAG, "Received spurious death notification for thread "
4658                    + thread.asBinder());
4659        }
4660    }
4661
4662    /**
4663     * If a stack trace dump file is configured, dump process stack traces.
4664     * @param clearTraces causes the dump file to be erased prior to the new
4665     *    traces being written, if true; when false, the new traces will be
4666     *    appended to any existing file content.
4667     * @param firstPids of dalvik VM processes to dump stack traces for first
4668     * @param lastPids of dalvik VM processes to dump stack traces for last
4669     * @param nativeProcs optional list of native process names to dump stack crawls
4670     * @return file containing stack traces, or null if no dump file is configured
4671     */
4672    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4673            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4674        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4675        if (tracesPath == null || tracesPath.length() == 0) {
4676            return null;
4677        }
4678
4679        File tracesFile = new File(tracesPath);
4680        try {
4681            File tracesDir = tracesFile.getParentFile();
4682            if (!tracesDir.exists()) {
4683                tracesDir.mkdirs();
4684                if (!SELinux.restorecon(tracesDir)) {
4685                    return null;
4686                }
4687            }
4688            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4689
4690            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4691            tracesFile.createNewFile();
4692            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4693        } catch (IOException e) {
4694            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4695            return null;
4696        }
4697
4698        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4699        return tracesFile;
4700    }
4701
4702    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4703            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4704        // Use a FileObserver to detect when traces finish writing.
4705        // The order of traces is considered important to maintain for legibility.
4706        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4707            @Override
4708            public synchronized void onEvent(int event, String path) { notify(); }
4709        };
4710
4711        try {
4712            observer.startWatching();
4713
4714            // First collect all of the stacks of the most important pids.
4715            if (firstPids != null) {
4716                try {
4717                    int num = firstPids.size();
4718                    for (int i = 0; i < num; i++) {
4719                        synchronized (observer) {
4720                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4721                            observer.wait(200);  // Wait for write-close, give up after 200msec
4722                        }
4723                    }
4724                } catch (InterruptedException e) {
4725                    Slog.wtf(TAG, e);
4726                }
4727            }
4728
4729            // Next collect the stacks of the native pids
4730            if (nativeProcs != null) {
4731                int[] pids = Process.getPidsForCommands(nativeProcs);
4732                if (pids != null) {
4733                    for (int pid : pids) {
4734                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4735                    }
4736                }
4737            }
4738
4739            // Lastly, measure CPU usage.
4740            if (processCpuTracker != null) {
4741                processCpuTracker.init();
4742                System.gc();
4743                processCpuTracker.update();
4744                try {
4745                    synchronized (processCpuTracker) {
4746                        processCpuTracker.wait(500); // measure over 1/2 second.
4747                    }
4748                } catch (InterruptedException e) {
4749                }
4750                processCpuTracker.update();
4751
4752                // We'll take the stack crawls of just the top apps using CPU.
4753                final int N = processCpuTracker.countWorkingStats();
4754                int numProcs = 0;
4755                for (int i=0; i<N && numProcs<5; i++) {
4756                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4757                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4758                        numProcs++;
4759                        try {
4760                            synchronized (observer) {
4761                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4762                                observer.wait(200);  // Wait for write-close, give up after 200msec
4763                            }
4764                        } catch (InterruptedException e) {
4765                            Slog.wtf(TAG, e);
4766                        }
4767
4768                    }
4769                }
4770            }
4771        } finally {
4772            observer.stopWatching();
4773        }
4774    }
4775
4776    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4777        if (true || IS_USER_BUILD) {
4778            return;
4779        }
4780        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4781        if (tracesPath == null || tracesPath.length() == 0) {
4782            return;
4783        }
4784
4785        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4786        StrictMode.allowThreadDiskWrites();
4787        try {
4788            final File tracesFile = new File(tracesPath);
4789            final File tracesDir = tracesFile.getParentFile();
4790            final File tracesTmp = new File(tracesDir, "__tmp__");
4791            try {
4792                if (!tracesDir.exists()) {
4793                    tracesDir.mkdirs();
4794                    if (!SELinux.restorecon(tracesDir.getPath())) {
4795                        return;
4796                    }
4797                }
4798                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4799
4800                if (tracesFile.exists()) {
4801                    tracesTmp.delete();
4802                    tracesFile.renameTo(tracesTmp);
4803                }
4804                StringBuilder sb = new StringBuilder();
4805                Time tobj = new Time();
4806                tobj.set(System.currentTimeMillis());
4807                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4808                sb.append(": ");
4809                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4810                sb.append(" since ");
4811                sb.append(msg);
4812                FileOutputStream fos = new FileOutputStream(tracesFile);
4813                fos.write(sb.toString().getBytes());
4814                if (app == null) {
4815                    fos.write("\n*** No application process!".getBytes());
4816                }
4817                fos.close();
4818                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4819            } catch (IOException e) {
4820                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4821                return;
4822            }
4823
4824            if (app != null) {
4825                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4826                firstPids.add(app.pid);
4827                dumpStackTraces(tracesPath, firstPids, null, null, null);
4828            }
4829
4830            File lastTracesFile = null;
4831            File curTracesFile = null;
4832            for (int i=9; i>=0; i--) {
4833                String name = String.format(Locale.US, "slow%02d.txt", i);
4834                curTracesFile = new File(tracesDir, name);
4835                if (curTracesFile.exists()) {
4836                    if (lastTracesFile != null) {
4837                        curTracesFile.renameTo(lastTracesFile);
4838                    } else {
4839                        curTracesFile.delete();
4840                    }
4841                }
4842                lastTracesFile = curTracesFile;
4843            }
4844            tracesFile.renameTo(curTracesFile);
4845            if (tracesTmp.exists()) {
4846                tracesTmp.renameTo(tracesFile);
4847            }
4848        } finally {
4849            StrictMode.setThreadPolicy(oldPolicy);
4850        }
4851    }
4852
4853    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4854            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4855        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4856        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4857
4858        if (mController != null) {
4859            try {
4860                // 0 == continue, -1 = kill process immediately
4861                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4862                if (res < 0 && app.pid != MY_PID) {
4863                    app.kill("anr", true);
4864                }
4865            } catch (RemoteException e) {
4866                mController = null;
4867                Watchdog.getInstance().setActivityController(null);
4868            }
4869        }
4870
4871        long anrTime = SystemClock.uptimeMillis();
4872        if (MONITOR_CPU_USAGE) {
4873            updateCpuStatsNow();
4874        }
4875
4876        synchronized (this) {
4877            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4878            if (mShuttingDown) {
4879                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4880                return;
4881            } else if (app.notResponding) {
4882                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4883                return;
4884            } else if (app.crashing) {
4885                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4886                return;
4887            }
4888
4889            // In case we come through here for the same app before completing
4890            // this one, mark as anring now so we will bail out.
4891            app.notResponding = true;
4892
4893            // Log the ANR to the event log.
4894            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4895                    app.processName, app.info.flags, annotation);
4896
4897            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4898            firstPids.add(app.pid);
4899
4900            int parentPid = app.pid;
4901            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4902            if (parentPid != app.pid) firstPids.add(parentPid);
4903
4904            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4905
4906            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4907                ProcessRecord r = mLruProcesses.get(i);
4908                if (r != null && r.thread != null) {
4909                    int pid = r.pid;
4910                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4911                        if (r.persistent) {
4912                            firstPids.add(pid);
4913                        } else {
4914                            lastPids.put(pid, Boolean.TRUE);
4915                        }
4916                    }
4917                }
4918            }
4919        }
4920
4921        // Log the ANR to the main log.
4922        StringBuilder info = new StringBuilder();
4923        info.setLength(0);
4924        info.append("ANR in ").append(app.processName);
4925        if (activity != null && activity.shortComponentName != null) {
4926            info.append(" (").append(activity.shortComponentName).append(")");
4927        }
4928        info.append("\n");
4929        info.append("PID: ").append(app.pid).append("\n");
4930        if (annotation != null) {
4931            info.append("Reason: ").append(annotation).append("\n");
4932        }
4933        if (parent != null && parent != activity) {
4934            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4935        }
4936
4937        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4938
4939        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4940                NATIVE_STACKS_OF_INTEREST);
4941
4942        String cpuInfo = null;
4943        if (MONITOR_CPU_USAGE) {
4944            updateCpuStatsNow();
4945            synchronized (mProcessCpuTracker) {
4946                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4947            }
4948            info.append(processCpuTracker.printCurrentLoad());
4949            info.append(cpuInfo);
4950        }
4951
4952        info.append(processCpuTracker.printCurrentState(anrTime));
4953
4954        Slog.e(TAG, info.toString());
4955        if (tracesFile == null) {
4956            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4957            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4958        }
4959
4960        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4961                cpuInfo, tracesFile, null);
4962
4963        if (mController != null) {
4964            try {
4965                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4966                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4967                if (res != 0) {
4968                    if (res < 0 && app.pid != MY_PID) {
4969                        app.kill("anr", true);
4970                    } else {
4971                        synchronized (this) {
4972                            mServices.scheduleServiceTimeoutLocked(app);
4973                        }
4974                    }
4975                    return;
4976                }
4977            } catch (RemoteException e) {
4978                mController = null;
4979                Watchdog.getInstance().setActivityController(null);
4980            }
4981        }
4982
4983        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4984        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4985                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4986
4987        synchronized (this) {
4988            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4989                app.kill("bg anr", true);
4990                return;
4991            }
4992
4993            // Set the app's notResponding state, and look up the errorReportReceiver
4994            makeAppNotRespondingLocked(app,
4995                    activity != null ? activity.shortComponentName : null,
4996                    annotation != null ? "ANR " + annotation : "ANR",
4997                    info.toString());
4998
4999            // Bring up the infamous App Not Responding dialog
5000            Message msg = Message.obtain();
5001            HashMap<String, Object> map = new HashMap<String, Object>();
5002            msg.what = SHOW_NOT_RESPONDING_MSG;
5003            msg.obj = map;
5004            msg.arg1 = aboveSystem ? 1 : 0;
5005            map.put("app", app);
5006            if (activity != null) {
5007                map.put("activity", activity);
5008            }
5009
5010            mHandler.sendMessage(msg);
5011        }
5012    }
5013
5014    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5015        if (!mLaunchWarningShown) {
5016            mLaunchWarningShown = true;
5017            mHandler.post(new Runnable() {
5018                @Override
5019                public void run() {
5020                    synchronized (ActivityManagerService.this) {
5021                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5022                        d.show();
5023                        mHandler.postDelayed(new Runnable() {
5024                            @Override
5025                            public void run() {
5026                                synchronized (ActivityManagerService.this) {
5027                                    d.dismiss();
5028                                    mLaunchWarningShown = false;
5029                                }
5030                            }
5031                        }, 4000);
5032                    }
5033                }
5034            });
5035        }
5036    }
5037
5038    @Override
5039    public boolean clearApplicationUserData(final String packageName,
5040            final IPackageDataObserver observer, int userId) {
5041        enforceNotIsolatedCaller("clearApplicationUserData");
5042        int uid = Binder.getCallingUid();
5043        int pid = Binder.getCallingPid();
5044        userId = handleIncomingUser(pid, uid,
5045                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5046        long callingId = Binder.clearCallingIdentity();
5047        try {
5048            IPackageManager pm = AppGlobals.getPackageManager();
5049            int pkgUid = -1;
5050            synchronized(this) {
5051                try {
5052                    pkgUid = pm.getPackageUid(packageName, userId);
5053                } catch (RemoteException e) {
5054                }
5055                if (pkgUid == -1) {
5056                    Slog.w(TAG, "Invalid packageName: " + packageName);
5057                    if (observer != null) {
5058                        try {
5059                            observer.onRemoveCompleted(packageName, false);
5060                        } catch (RemoteException e) {
5061                            Slog.i(TAG, "Observer no longer exists.");
5062                        }
5063                    }
5064                    return false;
5065                }
5066                if (uid == pkgUid || checkComponentPermission(
5067                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5068                        pid, uid, -1, true)
5069                        == PackageManager.PERMISSION_GRANTED) {
5070                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5071                } else {
5072                    throw new SecurityException("PID " + pid + " does not have permission "
5073                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5074                                    + " of package " + packageName);
5075                }
5076
5077                // Remove all tasks match the cleared application package and user
5078                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5079                    final TaskRecord tr = mRecentTasks.get(i);
5080                    final String taskPackageName =
5081                            tr.getBaseIntent().getComponent().getPackageName();
5082                    if (tr.userId != userId) continue;
5083                    if (!taskPackageName.equals(packageName)) continue;
5084                    removeTaskByIdLocked(tr.taskId, false);
5085                }
5086            }
5087
5088            try {
5089                // Clear application user data
5090                pm.clearApplicationUserData(packageName, observer, userId);
5091
5092                synchronized(this) {
5093                    // Remove all permissions granted from/to this package
5094                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5095                }
5096
5097                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5098                        Uri.fromParts("package", packageName, null));
5099                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5100                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5101                        null, null, 0, null, null, null, false, false, userId);
5102            } catch (RemoteException e) {
5103            }
5104        } finally {
5105            Binder.restoreCallingIdentity(callingId);
5106        }
5107        return true;
5108    }
5109
5110    @Override
5111    public void killBackgroundProcesses(final String packageName, int userId) {
5112        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5113                != PackageManager.PERMISSION_GRANTED &&
5114                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5115                        != PackageManager.PERMISSION_GRANTED) {
5116            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5117                    + Binder.getCallingPid()
5118                    + ", uid=" + Binder.getCallingUid()
5119                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5120            Slog.w(TAG, msg);
5121            throw new SecurityException(msg);
5122        }
5123
5124        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5125                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5126        long callingId = Binder.clearCallingIdentity();
5127        try {
5128            IPackageManager pm = AppGlobals.getPackageManager();
5129            synchronized(this) {
5130                int appId = -1;
5131                try {
5132                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5133                } catch (RemoteException e) {
5134                }
5135                if (appId == -1) {
5136                    Slog.w(TAG, "Invalid packageName: " + packageName);
5137                    return;
5138                }
5139                killPackageProcessesLocked(packageName, appId, userId,
5140                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5141            }
5142        } finally {
5143            Binder.restoreCallingIdentity(callingId);
5144        }
5145    }
5146
5147    @Override
5148    public void killAllBackgroundProcesses() {
5149        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5150                != PackageManager.PERMISSION_GRANTED) {
5151            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5152                    + Binder.getCallingPid()
5153                    + ", uid=" + Binder.getCallingUid()
5154                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5155            Slog.w(TAG, msg);
5156            throw new SecurityException(msg);
5157        }
5158
5159        long callingId = Binder.clearCallingIdentity();
5160        try {
5161            synchronized(this) {
5162                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5163                final int NP = mProcessNames.getMap().size();
5164                for (int ip=0; ip<NP; ip++) {
5165                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5166                    final int NA = apps.size();
5167                    for (int ia=0; ia<NA; ia++) {
5168                        ProcessRecord app = apps.valueAt(ia);
5169                        if (app.persistent) {
5170                            // we don't kill persistent processes
5171                            continue;
5172                        }
5173                        if (app.removed) {
5174                            procs.add(app);
5175                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5176                            app.removed = true;
5177                            procs.add(app);
5178                        }
5179                    }
5180                }
5181
5182                int N = procs.size();
5183                for (int i=0; i<N; i++) {
5184                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5185                }
5186                mAllowLowerMemLevel = true;
5187                updateOomAdjLocked();
5188                doLowMemReportIfNeededLocked(null);
5189            }
5190        } finally {
5191            Binder.restoreCallingIdentity(callingId);
5192        }
5193    }
5194
5195    @Override
5196    public void forceStopPackage(final String packageName, int userId) {
5197        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5198                != PackageManager.PERMISSION_GRANTED) {
5199            String msg = "Permission Denial: forceStopPackage() from pid="
5200                    + Binder.getCallingPid()
5201                    + ", uid=" + Binder.getCallingUid()
5202                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5203            Slog.w(TAG, msg);
5204            throw new SecurityException(msg);
5205        }
5206        final int callingPid = Binder.getCallingPid();
5207        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5208                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5209        long callingId = Binder.clearCallingIdentity();
5210        try {
5211            IPackageManager pm = AppGlobals.getPackageManager();
5212            synchronized(this) {
5213                int[] users = userId == UserHandle.USER_ALL
5214                        ? getUsersLocked() : new int[] { userId };
5215                for (int user : users) {
5216                    int pkgUid = -1;
5217                    try {
5218                        pkgUid = pm.getPackageUid(packageName, user);
5219                    } catch (RemoteException e) {
5220                    }
5221                    if (pkgUid == -1) {
5222                        Slog.w(TAG, "Invalid packageName: " + packageName);
5223                        continue;
5224                    }
5225                    try {
5226                        pm.setPackageStoppedState(packageName, true, user);
5227                    } catch (RemoteException e) {
5228                    } catch (IllegalArgumentException e) {
5229                        Slog.w(TAG, "Failed trying to unstop package "
5230                                + packageName + ": " + e);
5231                    }
5232                    if (isUserRunningLocked(user, false)) {
5233                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5234                    }
5235                }
5236            }
5237        } finally {
5238            Binder.restoreCallingIdentity(callingId);
5239        }
5240    }
5241
5242    @Override
5243    public void addPackageDependency(String packageName) {
5244        synchronized (this) {
5245            int callingPid = Binder.getCallingPid();
5246            if (callingPid == Process.myPid()) {
5247                //  Yeah, um, no.
5248                Slog.w(TAG, "Can't addPackageDependency on system process");
5249                return;
5250            }
5251            ProcessRecord proc;
5252            synchronized (mPidsSelfLocked) {
5253                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5254            }
5255            if (proc != null) {
5256                if (proc.pkgDeps == null) {
5257                    proc.pkgDeps = new ArraySet<String>(1);
5258                }
5259                proc.pkgDeps.add(packageName);
5260            }
5261        }
5262    }
5263
5264    /*
5265     * The pkg name and app id have to be specified.
5266     */
5267    @Override
5268    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5269        if (pkg == null) {
5270            return;
5271        }
5272        // Make sure the uid is valid.
5273        if (appid < 0) {
5274            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5275            return;
5276        }
5277        int callerUid = Binder.getCallingUid();
5278        // Only the system server can kill an application
5279        if (callerUid == Process.SYSTEM_UID) {
5280            // Post an aysnc message to kill the application
5281            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5282            msg.arg1 = appid;
5283            msg.arg2 = 0;
5284            Bundle bundle = new Bundle();
5285            bundle.putString("pkg", pkg);
5286            bundle.putString("reason", reason);
5287            msg.obj = bundle;
5288            mHandler.sendMessage(msg);
5289        } else {
5290            throw new SecurityException(callerUid + " cannot kill pkg: " +
5291                    pkg);
5292        }
5293    }
5294
5295    @Override
5296    public void closeSystemDialogs(String reason) {
5297        enforceNotIsolatedCaller("closeSystemDialogs");
5298
5299        final int pid = Binder.getCallingPid();
5300        final int uid = Binder.getCallingUid();
5301        final long origId = Binder.clearCallingIdentity();
5302        try {
5303            synchronized (this) {
5304                // Only allow this from foreground processes, so that background
5305                // applications can't abuse it to prevent system UI from being shown.
5306                if (uid >= Process.FIRST_APPLICATION_UID) {
5307                    ProcessRecord proc;
5308                    synchronized (mPidsSelfLocked) {
5309                        proc = mPidsSelfLocked.get(pid);
5310                    }
5311                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5312                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5313                                + " from background process " + proc);
5314                        return;
5315                    }
5316                }
5317                closeSystemDialogsLocked(reason);
5318            }
5319        } finally {
5320            Binder.restoreCallingIdentity(origId);
5321        }
5322    }
5323
5324    void closeSystemDialogsLocked(String reason) {
5325        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5326        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5327                | Intent.FLAG_RECEIVER_FOREGROUND);
5328        if (reason != null) {
5329            intent.putExtra("reason", reason);
5330        }
5331        mWindowManager.closeSystemDialogs(reason);
5332
5333        mStackSupervisor.closeSystemDialogsLocked();
5334
5335        broadcastIntentLocked(null, null, intent, null,
5336                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5337                Process.SYSTEM_UID, UserHandle.USER_ALL);
5338    }
5339
5340    @Override
5341    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5342        enforceNotIsolatedCaller("getProcessMemoryInfo");
5343        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5344        for (int i=pids.length-1; i>=0; i--) {
5345            ProcessRecord proc;
5346            int oomAdj;
5347            synchronized (this) {
5348                synchronized (mPidsSelfLocked) {
5349                    proc = mPidsSelfLocked.get(pids[i]);
5350                    oomAdj = proc != null ? proc.setAdj : 0;
5351                }
5352            }
5353            infos[i] = new Debug.MemoryInfo();
5354            Debug.getMemoryInfo(pids[i], infos[i]);
5355            if (proc != null) {
5356                synchronized (this) {
5357                    if (proc.thread != null && proc.setAdj == oomAdj) {
5358                        // Record this for posterity if the process has been stable.
5359                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5360                                infos[i].getTotalUss(), false, proc.pkgList);
5361                    }
5362                }
5363            }
5364        }
5365        return infos;
5366    }
5367
5368    @Override
5369    public long[] getProcessPss(int[] pids) {
5370        enforceNotIsolatedCaller("getProcessPss");
5371        long[] pss = new long[pids.length];
5372        for (int i=pids.length-1; i>=0; i--) {
5373            ProcessRecord proc;
5374            int oomAdj;
5375            synchronized (this) {
5376                synchronized (mPidsSelfLocked) {
5377                    proc = mPidsSelfLocked.get(pids[i]);
5378                    oomAdj = proc != null ? proc.setAdj : 0;
5379                }
5380            }
5381            long[] tmpUss = new long[1];
5382            pss[i] = Debug.getPss(pids[i], tmpUss);
5383            if (proc != null) {
5384                synchronized (this) {
5385                    if (proc.thread != null && proc.setAdj == oomAdj) {
5386                        // Record this for posterity if the process has been stable.
5387                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5388                    }
5389                }
5390            }
5391        }
5392        return pss;
5393    }
5394
5395    @Override
5396    public void killApplicationProcess(String processName, int uid) {
5397        if (processName == null) {
5398            return;
5399        }
5400
5401        int callerUid = Binder.getCallingUid();
5402        // Only the system server can kill an application
5403        if (callerUid == Process.SYSTEM_UID) {
5404            synchronized (this) {
5405                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5406                if (app != null && app.thread != null) {
5407                    try {
5408                        app.thread.scheduleSuicide();
5409                    } catch (RemoteException e) {
5410                        // If the other end already died, then our work here is done.
5411                    }
5412                } else {
5413                    Slog.w(TAG, "Process/uid not found attempting kill of "
5414                            + processName + " / " + uid);
5415                }
5416            }
5417        } else {
5418            throw new SecurityException(callerUid + " cannot kill app process: " +
5419                    processName);
5420        }
5421    }
5422
5423    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5424        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5425                false, true, false, false, UserHandle.getUserId(uid), reason);
5426        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5427                Uri.fromParts("package", packageName, null));
5428        if (!mProcessesReady) {
5429            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5430                    | Intent.FLAG_RECEIVER_FOREGROUND);
5431        }
5432        intent.putExtra(Intent.EXTRA_UID, uid);
5433        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5434        broadcastIntentLocked(null, null, intent,
5435                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5436                false, false,
5437                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5438    }
5439
5440    private void forceStopUserLocked(int userId, String reason) {
5441        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5442        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5443        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5444                | Intent.FLAG_RECEIVER_FOREGROUND);
5445        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5446        broadcastIntentLocked(null, null, intent,
5447                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5448                false, false,
5449                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5450    }
5451
5452    private final boolean killPackageProcessesLocked(String packageName, int appId,
5453            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5454            boolean doit, boolean evenPersistent, String reason) {
5455        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5456
5457        // Remove all processes this package may have touched: all with the
5458        // same UID (except for the system or root user), and all whose name
5459        // matches the package name.
5460        final int NP = mProcessNames.getMap().size();
5461        for (int ip=0; ip<NP; ip++) {
5462            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5463            final int NA = apps.size();
5464            for (int ia=0; ia<NA; ia++) {
5465                ProcessRecord app = apps.valueAt(ia);
5466                if (app.persistent && !evenPersistent) {
5467                    // we don't kill persistent processes
5468                    continue;
5469                }
5470                if (app.removed) {
5471                    if (doit) {
5472                        procs.add(app);
5473                    }
5474                    continue;
5475                }
5476
5477                // Skip process if it doesn't meet our oom adj requirement.
5478                if (app.setAdj < minOomAdj) {
5479                    continue;
5480                }
5481
5482                // If no package is specified, we call all processes under the
5483                // give user id.
5484                if (packageName == null) {
5485                    if (app.userId != userId) {
5486                        continue;
5487                    }
5488                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5489                        continue;
5490                    }
5491                // Package has been specified, we want to hit all processes
5492                // that match it.  We need to qualify this by the processes
5493                // that are running under the specified app and user ID.
5494                } else {
5495                    final boolean isDep = app.pkgDeps != null
5496                            && app.pkgDeps.contains(packageName);
5497                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5498                        continue;
5499                    }
5500                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5501                        continue;
5502                    }
5503                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5504                        continue;
5505                    }
5506                }
5507
5508                // Process has passed all conditions, kill it!
5509                if (!doit) {
5510                    return true;
5511                }
5512                app.removed = true;
5513                procs.add(app);
5514            }
5515        }
5516
5517        int N = procs.size();
5518        for (int i=0; i<N; i++) {
5519            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5520        }
5521        updateOomAdjLocked();
5522        return N > 0;
5523    }
5524
5525    private final boolean forceStopPackageLocked(String name, int appId,
5526            boolean callerWillRestart, boolean purgeCache, boolean doit,
5527            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5528        int i;
5529        int N;
5530
5531        if (userId == UserHandle.USER_ALL && name == null) {
5532            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5533        }
5534
5535        if (appId < 0 && name != null) {
5536            try {
5537                appId = UserHandle.getAppId(
5538                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5539            } catch (RemoteException e) {
5540            }
5541        }
5542
5543        if (doit) {
5544            if (name != null) {
5545                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5546                        + " user=" + userId + ": " + reason);
5547            } else {
5548                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5549            }
5550
5551            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5552            for (int ip=pmap.size()-1; ip>=0; ip--) {
5553                SparseArray<Long> ba = pmap.valueAt(ip);
5554                for (i=ba.size()-1; i>=0; i--) {
5555                    boolean remove = false;
5556                    final int entUid = ba.keyAt(i);
5557                    if (name != null) {
5558                        if (userId == UserHandle.USER_ALL) {
5559                            if (UserHandle.getAppId(entUid) == appId) {
5560                                remove = true;
5561                            }
5562                        } else {
5563                            if (entUid == UserHandle.getUid(userId, appId)) {
5564                                remove = true;
5565                            }
5566                        }
5567                    } else if (UserHandle.getUserId(entUid) == userId) {
5568                        remove = true;
5569                    }
5570                    if (remove) {
5571                        ba.removeAt(i);
5572                    }
5573                }
5574                if (ba.size() == 0) {
5575                    pmap.removeAt(ip);
5576                }
5577            }
5578        }
5579
5580        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5581                -100, callerWillRestart, true, doit, evenPersistent,
5582                name == null ? ("stop user " + userId) : ("stop " + name));
5583
5584        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5585            if (!doit) {
5586                return true;
5587            }
5588            didSomething = true;
5589        }
5590
5591        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5592            if (!doit) {
5593                return true;
5594            }
5595            didSomething = true;
5596        }
5597
5598        if (name == null) {
5599            // Remove all sticky broadcasts from this user.
5600            mStickyBroadcasts.remove(userId);
5601        }
5602
5603        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5604        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5605                userId, providers)) {
5606            if (!doit) {
5607                return true;
5608            }
5609            didSomething = true;
5610        }
5611        N = providers.size();
5612        for (i=0; i<N; i++) {
5613            removeDyingProviderLocked(null, providers.get(i), true);
5614        }
5615
5616        // Remove transient permissions granted from/to this package/user
5617        removeUriPermissionsForPackageLocked(name, userId, false);
5618
5619        if (name == null || uninstalling) {
5620            // Remove pending intents.  For now we only do this when force
5621            // stopping users, because we have some problems when doing this
5622            // for packages -- app widgets are not currently cleaned up for
5623            // such packages, so they can be left with bad pending intents.
5624            if (mIntentSenderRecords.size() > 0) {
5625                Iterator<WeakReference<PendingIntentRecord>> it
5626                        = mIntentSenderRecords.values().iterator();
5627                while (it.hasNext()) {
5628                    WeakReference<PendingIntentRecord> wpir = it.next();
5629                    if (wpir == null) {
5630                        it.remove();
5631                        continue;
5632                    }
5633                    PendingIntentRecord pir = wpir.get();
5634                    if (pir == null) {
5635                        it.remove();
5636                        continue;
5637                    }
5638                    if (name == null) {
5639                        // Stopping user, remove all objects for the user.
5640                        if (pir.key.userId != userId) {
5641                            // Not the same user, skip it.
5642                            continue;
5643                        }
5644                    } else {
5645                        if (UserHandle.getAppId(pir.uid) != appId) {
5646                            // Different app id, skip it.
5647                            continue;
5648                        }
5649                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5650                            // Different user, skip it.
5651                            continue;
5652                        }
5653                        if (!pir.key.packageName.equals(name)) {
5654                            // Different package, skip it.
5655                            continue;
5656                        }
5657                    }
5658                    if (!doit) {
5659                        return true;
5660                    }
5661                    didSomething = true;
5662                    it.remove();
5663                    pir.canceled = true;
5664                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5665                        pir.key.activity.pendingResults.remove(pir.ref);
5666                    }
5667                }
5668            }
5669        }
5670
5671        if (doit) {
5672            if (purgeCache && name != null) {
5673                AttributeCache ac = AttributeCache.instance();
5674                if (ac != null) {
5675                    ac.removePackage(name);
5676                }
5677            }
5678            if (mBooted) {
5679                mStackSupervisor.resumeTopActivitiesLocked();
5680                mStackSupervisor.scheduleIdleLocked();
5681            }
5682        }
5683
5684        return didSomething;
5685    }
5686
5687    private final boolean removeProcessLocked(ProcessRecord app,
5688            boolean callerWillRestart, boolean allowRestart, String reason) {
5689        final String name = app.processName;
5690        final int uid = app.uid;
5691        if (DEBUG_PROCESSES) Slog.d(
5692            TAG, "Force removing proc " + app.toShortString() + " (" + name
5693            + "/" + uid + ")");
5694
5695        mProcessNames.remove(name, uid);
5696        mIsolatedProcesses.remove(app.uid);
5697        if (mHeavyWeightProcess == app) {
5698            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5699                    mHeavyWeightProcess.userId, 0));
5700            mHeavyWeightProcess = null;
5701        }
5702        boolean needRestart = false;
5703        if (app.pid > 0 && app.pid != MY_PID) {
5704            int pid = app.pid;
5705            synchronized (mPidsSelfLocked) {
5706                mPidsSelfLocked.remove(pid);
5707                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5708            }
5709            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5710            if (app.isolated) {
5711                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5712            }
5713            app.kill(reason, true);
5714            handleAppDiedLocked(app, true, allowRestart);
5715            removeLruProcessLocked(app);
5716
5717            if (app.persistent && !app.isolated) {
5718                if (!callerWillRestart) {
5719                    addAppLocked(app.info, false, null /* ABI override */);
5720                } else {
5721                    needRestart = true;
5722                }
5723            }
5724        } else {
5725            mRemovedProcesses.add(app);
5726        }
5727
5728        return needRestart;
5729    }
5730
5731    private final void processStartTimedOutLocked(ProcessRecord app) {
5732        final int pid = app.pid;
5733        boolean gone = false;
5734        synchronized (mPidsSelfLocked) {
5735            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5736            if (knownApp != null && knownApp.thread == null) {
5737                mPidsSelfLocked.remove(pid);
5738                gone = true;
5739            }
5740        }
5741
5742        if (gone) {
5743            Slog.w(TAG, "Process " + app + " failed to attach");
5744            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5745                    pid, app.uid, app.processName);
5746            mProcessNames.remove(app.processName, app.uid);
5747            mIsolatedProcesses.remove(app.uid);
5748            if (mHeavyWeightProcess == app) {
5749                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5750                        mHeavyWeightProcess.userId, 0));
5751                mHeavyWeightProcess = null;
5752            }
5753            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5754            if (app.isolated) {
5755                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5756            }
5757            // Take care of any launching providers waiting for this process.
5758            checkAppInLaunchingProvidersLocked(app, true);
5759            // Take care of any services that are waiting for the process.
5760            mServices.processStartTimedOutLocked(app);
5761            app.kill("start timeout", true);
5762            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5763                Slog.w(TAG, "Unattached app died before backup, skipping");
5764                try {
5765                    IBackupManager bm = IBackupManager.Stub.asInterface(
5766                            ServiceManager.getService(Context.BACKUP_SERVICE));
5767                    bm.agentDisconnected(app.info.packageName);
5768                } catch (RemoteException e) {
5769                    // Can't happen; the backup manager is local
5770                }
5771            }
5772            if (isPendingBroadcastProcessLocked(pid)) {
5773                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5774                skipPendingBroadcastLocked(pid);
5775            }
5776        } else {
5777            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5778        }
5779    }
5780
5781    private final boolean attachApplicationLocked(IApplicationThread thread,
5782            int pid) {
5783
5784        // Find the application record that is being attached...  either via
5785        // the pid if we are running in multiple processes, or just pull the
5786        // next app record if we are emulating process with anonymous threads.
5787        ProcessRecord app;
5788        if (pid != MY_PID && pid >= 0) {
5789            synchronized (mPidsSelfLocked) {
5790                app = mPidsSelfLocked.get(pid);
5791            }
5792        } else {
5793            app = null;
5794        }
5795
5796        if (app == null) {
5797            Slog.w(TAG, "No pending application record for pid " + pid
5798                    + " (IApplicationThread " + thread + "); dropping process");
5799            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5800            if (pid > 0 && pid != MY_PID) {
5801                Process.killProcessQuiet(pid);
5802                //TODO: Process.killProcessGroup(app.info.uid, pid);
5803            } else {
5804                try {
5805                    thread.scheduleExit();
5806                } catch (Exception e) {
5807                    // Ignore exceptions.
5808                }
5809            }
5810            return false;
5811        }
5812
5813        // If this application record is still attached to a previous
5814        // process, clean it up now.
5815        if (app.thread != null) {
5816            handleAppDiedLocked(app, true, true);
5817        }
5818
5819        // Tell the process all about itself.
5820
5821        if (localLOGV) Slog.v(
5822                TAG, "Binding process pid " + pid + " to record " + app);
5823
5824        final String processName = app.processName;
5825        try {
5826            AppDeathRecipient adr = new AppDeathRecipient(
5827                    app, pid, thread);
5828            thread.asBinder().linkToDeath(adr, 0);
5829            app.deathRecipient = adr;
5830        } catch (RemoteException e) {
5831            app.resetPackageList(mProcessStats);
5832            startProcessLocked(app, "link fail", processName);
5833            return false;
5834        }
5835
5836        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5837
5838        app.makeActive(thread, mProcessStats);
5839        app.curAdj = app.setAdj = -100;
5840        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5841        app.forcingToForeground = null;
5842        updateProcessForegroundLocked(app, false, false);
5843        app.hasShownUi = false;
5844        app.debugging = false;
5845        app.cached = false;
5846
5847        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5848
5849        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5850        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5851
5852        if (!normalMode) {
5853            Slog.i(TAG, "Launching preboot mode app: " + app);
5854        }
5855
5856        if (localLOGV) Slog.v(
5857            TAG, "New app record " + app
5858            + " thread=" + thread.asBinder() + " pid=" + pid);
5859        try {
5860            int testMode = IApplicationThread.DEBUG_OFF;
5861            if (mDebugApp != null && mDebugApp.equals(processName)) {
5862                testMode = mWaitForDebugger
5863                    ? IApplicationThread.DEBUG_WAIT
5864                    : IApplicationThread.DEBUG_ON;
5865                app.debugging = true;
5866                if (mDebugTransient) {
5867                    mDebugApp = mOrigDebugApp;
5868                    mWaitForDebugger = mOrigWaitForDebugger;
5869                }
5870            }
5871            String profileFile = app.instrumentationProfileFile;
5872            ParcelFileDescriptor profileFd = null;
5873            int samplingInterval = 0;
5874            boolean profileAutoStop = false;
5875            if (mProfileApp != null && mProfileApp.equals(processName)) {
5876                mProfileProc = app;
5877                profileFile = mProfileFile;
5878                profileFd = mProfileFd;
5879                samplingInterval = mSamplingInterval;
5880                profileAutoStop = mAutoStopProfiler;
5881            }
5882            boolean enableOpenGlTrace = false;
5883            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5884                enableOpenGlTrace = true;
5885                mOpenGlTraceApp = null;
5886            }
5887
5888            // If the app is being launched for restore or full backup, set it up specially
5889            boolean isRestrictedBackupMode = false;
5890            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5891                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5892                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5893                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5894            }
5895
5896            ensurePackageDexOpt(app.instrumentationInfo != null
5897                    ? app.instrumentationInfo.packageName
5898                    : app.info.packageName);
5899            if (app.instrumentationClass != null) {
5900                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5901            }
5902            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5903                    + processName + " with config " + mConfiguration);
5904            ApplicationInfo appInfo = app.instrumentationInfo != null
5905                    ? app.instrumentationInfo : app.info;
5906            app.compat = compatibilityInfoForPackageLocked(appInfo);
5907            if (profileFd != null) {
5908                profileFd = profileFd.dup();
5909            }
5910            ProfilerInfo profilerInfo = profileFile == null ? null
5911                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5912            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5913                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5914                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5915                    isRestrictedBackupMode || !normalMode, app.persistent,
5916                    new Configuration(mConfiguration), app.compat,
5917                    getCommonServicesLocked(app.isolated),
5918                    mCoreSettingsObserver.getCoreSettingsLocked());
5919            updateLruProcessLocked(app, false, null);
5920            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5921        } catch (Exception e) {
5922            // todo: Yikes!  What should we do?  For now we will try to
5923            // start another process, but that could easily get us in
5924            // an infinite loop of restarting processes...
5925            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5926
5927            app.resetPackageList(mProcessStats);
5928            app.unlinkDeathRecipient();
5929            startProcessLocked(app, "bind fail", processName);
5930            return false;
5931        }
5932
5933        // Remove this record from the list of starting applications.
5934        mPersistentStartingProcesses.remove(app);
5935        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5936                "Attach application locked removing on hold: " + app);
5937        mProcessesOnHold.remove(app);
5938
5939        boolean badApp = false;
5940        boolean didSomething = false;
5941
5942        // See if the top visible activity is waiting to run in this process...
5943        if (normalMode) {
5944            try {
5945                if (mStackSupervisor.attachApplicationLocked(app)) {
5946                    didSomething = true;
5947                }
5948            } catch (Exception e) {
5949                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5950                badApp = true;
5951            }
5952        }
5953
5954        // Find any services that should be running in this process...
5955        if (!badApp) {
5956            try {
5957                didSomething |= mServices.attachApplicationLocked(app, processName);
5958            } catch (Exception e) {
5959                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5960                badApp = true;
5961            }
5962        }
5963
5964        // Check if a next-broadcast receiver is in this process...
5965        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5966            try {
5967                didSomething |= sendPendingBroadcastsLocked(app);
5968            } catch (Exception e) {
5969                // If the app died trying to launch the receiver we declare it 'bad'
5970                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
5971                badApp = true;
5972            }
5973        }
5974
5975        // Check whether the next backup agent is in this process...
5976        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5977            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5978            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5979            try {
5980                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5981                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5982                        mBackupTarget.backupMode);
5983            } catch (Exception e) {
5984                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
5985                badApp = true;
5986            }
5987        }
5988
5989        if (badApp) {
5990            app.kill("error during init", true);
5991            handleAppDiedLocked(app, false, true);
5992            return false;
5993        }
5994
5995        if (!didSomething) {
5996            updateOomAdjLocked();
5997        }
5998
5999        return true;
6000    }
6001
6002    @Override
6003    public final void attachApplication(IApplicationThread thread) {
6004        synchronized (this) {
6005            int callingPid = Binder.getCallingPid();
6006            final long origId = Binder.clearCallingIdentity();
6007            attachApplicationLocked(thread, callingPid);
6008            Binder.restoreCallingIdentity(origId);
6009        }
6010    }
6011
6012    @Override
6013    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6014        final long origId = Binder.clearCallingIdentity();
6015        synchronized (this) {
6016            ActivityStack stack = ActivityRecord.getStackLocked(token);
6017            if (stack != null) {
6018                ActivityRecord r =
6019                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6020                if (stopProfiling) {
6021                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6022                        try {
6023                            mProfileFd.close();
6024                        } catch (IOException e) {
6025                        }
6026                        clearProfilerLocked();
6027                    }
6028                }
6029            }
6030        }
6031        Binder.restoreCallingIdentity(origId);
6032    }
6033
6034    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6035        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6036                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6037    }
6038
6039    void enableScreenAfterBoot() {
6040        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6041                SystemClock.uptimeMillis());
6042        mWindowManager.enableScreenAfterBoot();
6043
6044        synchronized (this) {
6045            updateEventDispatchingLocked();
6046        }
6047    }
6048
6049    @Override
6050    public void showBootMessage(final CharSequence msg, final boolean always) {
6051        enforceNotIsolatedCaller("showBootMessage");
6052        mWindowManager.showBootMessage(msg, always);
6053    }
6054
6055    @Override
6056    public void keyguardWaitingForActivityDrawn() {
6057        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6058        final long token = Binder.clearCallingIdentity();
6059        try {
6060            synchronized (this) {
6061                if (DEBUG_LOCKSCREEN) logLockScreen("");
6062                mWindowManager.keyguardWaitingForActivityDrawn();
6063                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6064                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6065                    updateSleepIfNeededLocked();
6066                }
6067            }
6068        } finally {
6069            Binder.restoreCallingIdentity(token);
6070        }
6071    }
6072
6073    final void finishBooting() {
6074        synchronized (this) {
6075            if (!mBootAnimationComplete) {
6076                mCallFinishBooting = true;
6077                return;
6078            }
6079            mCallFinishBooting = false;
6080        }
6081
6082        ArraySet<String> completedIsas = new ArraySet<String>();
6083        for (String abi : Build.SUPPORTED_ABIS) {
6084            Process.establishZygoteConnectionForAbi(abi);
6085            final String instructionSet = VMRuntime.getInstructionSet(abi);
6086            if (!completedIsas.contains(instructionSet)) {
6087                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6088                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6089                }
6090                completedIsas.add(instructionSet);
6091            }
6092        }
6093
6094        IntentFilter pkgFilter = new IntentFilter();
6095        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6096        pkgFilter.addDataScheme("package");
6097        mContext.registerReceiver(new BroadcastReceiver() {
6098            @Override
6099            public void onReceive(Context context, Intent intent) {
6100                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6101                if (pkgs != null) {
6102                    for (String pkg : pkgs) {
6103                        synchronized (ActivityManagerService.this) {
6104                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6105                                    0, "finished booting")) {
6106                                setResultCode(Activity.RESULT_OK);
6107                                return;
6108                            }
6109                        }
6110                    }
6111                }
6112            }
6113        }, pkgFilter);
6114
6115        // Let system services know.
6116        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6117
6118        synchronized (this) {
6119            // Ensure that any processes we had put on hold are now started
6120            // up.
6121            final int NP = mProcessesOnHold.size();
6122            if (NP > 0) {
6123                ArrayList<ProcessRecord> procs =
6124                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6125                for (int ip=0; ip<NP; ip++) {
6126                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6127                            + procs.get(ip));
6128                    startProcessLocked(procs.get(ip), "on-hold", null);
6129                }
6130            }
6131
6132            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6133                // Start looking for apps that are abusing wake locks.
6134                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6135                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6136                // Tell anyone interested that we are done booting!
6137                SystemProperties.set("sys.boot_completed", "1");
6138
6139                // And trigger dev.bootcomplete if we are not showing encryption progress
6140                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6141                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6142                    SystemProperties.set("dev.bootcomplete", "1");
6143                }
6144                for (int i=0; i<mStartedUsers.size(); i++) {
6145                    UserStartedState uss = mStartedUsers.valueAt(i);
6146                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6147                        uss.mState = UserStartedState.STATE_RUNNING;
6148                        final int userId = mStartedUsers.keyAt(i);
6149                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6150                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6151                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6152                        broadcastIntentLocked(null, null, intent, null,
6153                                new IIntentReceiver.Stub() {
6154                                    @Override
6155                                    public void performReceive(Intent intent, int resultCode,
6156                                            String data, Bundle extras, boolean ordered,
6157                                            boolean sticky, int sendingUser) {
6158                                        synchronized (ActivityManagerService.this) {
6159                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6160                                                    true, false);
6161                                        }
6162                                    }
6163                                },
6164                                0, null, null,
6165                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6166                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6167                                userId);
6168                    }
6169                }
6170                scheduleStartProfilesLocked();
6171            }
6172        }
6173    }
6174
6175    @Override
6176    public void bootAnimationComplete() {
6177        final boolean callFinishBooting;
6178        synchronized (this) {
6179            callFinishBooting = mCallFinishBooting;
6180            mBootAnimationComplete = true;
6181        }
6182        if (callFinishBooting) {
6183            finishBooting();
6184        }
6185    }
6186
6187    final void ensureBootCompleted() {
6188        boolean booting;
6189        boolean enableScreen;
6190        synchronized (this) {
6191            booting = mBooting;
6192            mBooting = false;
6193            enableScreen = !mBooted;
6194            mBooted = true;
6195        }
6196
6197        if (booting) {
6198            finishBooting();
6199        }
6200
6201        if (enableScreen) {
6202            enableScreenAfterBoot();
6203        }
6204    }
6205
6206    @Override
6207    public final void activityResumed(IBinder token) {
6208        final long origId = Binder.clearCallingIdentity();
6209        synchronized(this) {
6210            ActivityStack stack = ActivityRecord.getStackLocked(token);
6211            if (stack != null) {
6212                ActivityRecord.activityResumedLocked(token);
6213            }
6214        }
6215        Binder.restoreCallingIdentity(origId);
6216    }
6217
6218    @Override
6219    public final void activityPaused(IBinder token) {
6220        final long origId = Binder.clearCallingIdentity();
6221        synchronized(this) {
6222            ActivityStack stack = ActivityRecord.getStackLocked(token);
6223            if (stack != null) {
6224                stack.activityPausedLocked(token, false);
6225            }
6226        }
6227        Binder.restoreCallingIdentity(origId);
6228    }
6229
6230    @Override
6231    public final void activityStopped(IBinder token, Bundle icicle,
6232            PersistableBundle persistentState, CharSequence description) {
6233        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6234
6235        // Refuse possible leaked file descriptors
6236        if (icicle != null && icicle.hasFileDescriptors()) {
6237            throw new IllegalArgumentException("File descriptors passed in Bundle");
6238        }
6239
6240        final long origId = Binder.clearCallingIdentity();
6241
6242        synchronized (this) {
6243            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6244            if (r != null) {
6245                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6246            }
6247        }
6248
6249        trimApplications();
6250
6251        Binder.restoreCallingIdentity(origId);
6252    }
6253
6254    @Override
6255    public final void activityDestroyed(IBinder token) {
6256        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6257        synchronized (this) {
6258            ActivityStack stack = ActivityRecord.getStackLocked(token);
6259            if (stack != null) {
6260                stack.activityDestroyedLocked(token);
6261            }
6262        }
6263    }
6264
6265    @Override
6266    public final void backgroundResourcesReleased(IBinder token) {
6267        final long origId = Binder.clearCallingIdentity();
6268        try {
6269            synchronized (this) {
6270                ActivityStack stack = ActivityRecord.getStackLocked(token);
6271                if (stack != null) {
6272                    stack.backgroundResourcesReleased();
6273                }
6274            }
6275        } finally {
6276            Binder.restoreCallingIdentity(origId);
6277        }
6278    }
6279
6280    @Override
6281    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6282        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6283    }
6284
6285    @Override
6286    public final void notifyEnterAnimationComplete(IBinder token) {
6287        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6288    }
6289
6290    @Override
6291    public String getCallingPackage(IBinder token) {
6292        synchronized (this) {
6293            ActivityRecord r = getCallingRecordLocked(token);
6294            return r != null ? r.info.packageName : null;
6295        }
6296    }
6297
6298    @Override
6299    public ComponentName getCallingActivity(IBinder token) {
6300        synchronized (this) {
6301            ActivityRecord r = getCallingRecordLocked(token);
6302            return r != null ? r.intent.getComponent() : null;
6303        }
6304    }
6305
6306    private ActivityRecord getCallingRecordLocked(IBinder token) {
6307        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6308        if (r == null) {
6309            return null;
6310        }
6311        return r.resultTo;
6312    }
6313
6314    @Override
6315    public ComponentName getActivityClassForToken(IBinder token) {
6316        synchronized(this) {
6317            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6318            if (r == null) {
6319                return null;
6320            }
6321            return r.intent.getComponent();
6322        }
6323    }
6324
6325    @Override
6326    public String getPackageForToken(IBinder token) {
6327        synchronized(this) {
6328            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6329            if (r == null) {
6330                return null;
6331            }
6332            return r.packageName;
6333        }
6334    }
6335
6336    @Override
6337    public IIntentSender getIntentSender(int type,
6338            String packageName, IBinder token, String resultWho,
6339            int requestCode, Intent[] intents, String[] resolvedTypes,
6340            int flags, Bundle options, int userId) {
6341        enforceNotIsolatedCaller("getIntentSender");
6342        // Refuse possible leaked file descriptors
6343        if (intents != null) {
6344            if (intents.length < 1) {
6345                throw new IllegalArgumentException("Intents array length must be >= 1");
6346            }
6347            for (int i=0; i<intents.length; i++) {
6348                Intent intent = intents[i];
6349                if (intent != null) {
6350                    if (intent.hasFileDescriptors()) {
6351                        throw new IllegalArgumentException("File descriptors passed in Intent");
6352                    }
6353                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6354                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6355                        throw new IllegalArgumentException(
6356                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6357                    }
6358                    intents[i] = new Intent(intent);
6359                }
6360            }
6361            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6362                throw new IllegalArgumentException(
6363                        "Intent array length does not match resolvedTypes length");
6364            }
6365        }
6366        if (options != null) {
6367            if (options.hasFileDescriptors()) {
6368                throw new IllegalArgumentException("File descriptors passed in options");
6369            }
6370        }
6371
6372        synchronized(this) {
6373            int callingUid = Binder.getCallingUid();
6374            int origUserId = userId;
6375            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6376                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6377                    ALLOW_NON_FULL, "getIntentSender", null);
6378            if (origUserId == UserHandle.USER_CURRENT) {
6379                // We don't want to evaluate this until the pending intent is
6380                // actually executed.  However, we do want to always do the
6381                // security checking for it above.
6382                userId = UserHandle.USER_CURRENT;
6383            }
6384            try {
6385                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6386                    int uid = AppGlobals.getPackageManager()
6387                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6388                    if (!UserHandle.isSameApp(callingUid, uid)) {
6389                        String msg = "Permission Denial: getIntentSender() from pid="
6390                            + Binder.getCallingPid()
6391                            + ", uid=" + Binder.getCallingUid()
6392                            + ", (need uid=" + uid + ")"
6393                            + " is not allowed to send as package " + packageName;
6394                        Slog.w(TAG, msg);
6395                        throw new SecurityException(msg);
6396                    }
6397                }
6398
6399                return getIntentSenderLocked(type, packageName, callingUid, userId,
6400                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6401
6402            } catch (RemoteException e) {
6403                throw new SecurityException(e);
6404            }
6405        }
6406    }
6407
6408    IIntentSender getIntentSenderLocked(int type, String packageName,
6409            int callingUid, int userId, IBinder token, String resultWho,
6410            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6411            Bundle options) {
6412        if (DEBUG_MU)
6413            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6414        ActivityRecord activity = null;
6415        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6416            activity = ActivityRecord.isInStackLocked(token);
6417            if (activity == null) {
6418                return null;
6419            }
6420            if (activity.finishing) {
6421                return null;
6422            }
6423        }
6424
6425        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6426        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6427        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6428        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6429                |PendingIntent.FLAG_UPDATE_CURRENT);
6430
6431        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6432                type, packageName, activity, resultWho,
6433                requestCode, intents, resolvedTypes, flags, options, userId);
6434        WeakReference<PendingIntentRecord> ref;
6435        ref = mIntentSenderRecords.get(key);
6436        PendingIntentRecord rec = ref != null ? ref.get() : null;
6437        if (rec != null) {
6438            if (!cancelCurrent) {
6439                if (updateCurrent) {
6440                    if (rec.key.requestIntent != null) {
6441                        rec.key.requestIntent.replaceExtras(intents != null ?
6442                                intents[intents.length - 1] : null);
6443                    }
6444                    if (intents != null) {
6445                        intents[intents.length-1] = rec.key.requestIntent;
6446                        rec.key.allIntents = intents;
6447                        rec.key.allResolvedTypes = resolvedTypes;
6448                    } else {
6449                        rec.key.allIntents = null;
6450                        rec.key.allResolvedTypes = null;
6451                    }
6452                }
6453                return rec;
6454            }
6455            rec.canceled = true;
6456            mIntentSenderRecords.remove(key);
6457        }
6458        if (noCreate) {
6459            return rec;
6460        }
6461        rec = new PendingIntentRecord(this, key, callingUid);
6462        mIntentSenderRecords.put(key, rec.ref);
6463        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6464            if (activity.pendingResults == null) {
6465                activity.pendingResults
6466                        = new HashSet<WeakReference<PendingIntentRecord>>();
6467            }
6468            activity.pendingResults.add(rec.ref);
6469        }
6470        return rec;
6471    }
6472
6473    @Override
6474    public void cancelIntentSender(IIntentSender sender) {
6475        if (!(sender instanceof PendingIntentRecord)) {
6476            return;
6477        }
6478        synchronized(this) {
6479            PendingIntentRecord rec = (PendingIntentRecord)sender;
6480            try {
6481                int uid = AppGlobals.getPackageManager()
6482                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6483                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6484                    String msg = "Permission Denial: cancelIntentSender() from pid="
6485                        + Binder.getCallingPid()
6486                        + ", uid=" + Binder.getCallingUid()
6487                        + " is not allowed to cancel packges "
6488                        + rec.key.packageName;
6489                    Slog.w(TAG, msg);
6490                    throw new SecurityException(msg);
6491                }
6492            } catch (RemoteException e) {
6493                throw new SecurityException(e);
6494            }
6495            cancelIntentSenderLocked(rec, true);
6496        }
6497    }
6498
6499    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6500        rec.canceled = true;
6501        mIntentSenderRecords.remove(rec.key);
6502        if (cleanActivity && rec.key.activity != null) {
6503            rec.key.activity.pendingResults.remove(rec.ref);
6504        }
6505    }
6506
6507    @Override
6508    public String getPackageForIntentSender(IIntentSender pendingResult) {
6509        if (!(pendingResult instanceof PendingIntentRecord)) {
6510            return null;
6511        }
6512        try {
6513            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6514            return res.key.packageName;
6515        } catch (ClassCastException e) {
6516        }
6517        return null;
6518    }
6519
6520    @Override
6521    public int getUidForIntentSender(IIntentSender sender) {
6522        if (sender instanceof PendingIntentRecord) {
6523            try {
6524                PendingIntentRecord res = (PendingIntentRecord)sender;
6525                return res.uid;
6526            } catch (ClassCastException e) {
6527            }
6528        }
6529        return -1;
6530    }
6531
6532    @Override
6533    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6534        if (!(pendingResult instanceof PendingIntentRecord)) {
6535            return false;
6536        }
6537        try {
6538            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6539            if (res.key.allIntents == null) {
6540                return false;
6541            }
6542            for (int i=0; i<res.key.allIntents.length; i++) {
6543                Intent intent = res.key.allIntents[i];
6544                if (intent.getPackage() != null && intent.getComponent() != null) {
6545                    return false;
6546                }
6547            }
6548            return true;
6549        } catch (ClassCastException e) {
6550        }
6551        return false;
6552    }
6553
6554    @Override
6555    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6556        if (!(pendingResult instanceof PendingIntentRecord)) {
6557            return false;
6558        }
6559        try {
6560            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6561            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6562                return true;
6563            }
6564            return false;
6565        } catch (ClassCastException e) {
6566        }
6567        return false;
6568    }
6569
6570    @Override
6571    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6572        if (!(pendingResult instanceof PendingIntentRecord)) {
6573            return null;
6574        }
6575        try {
6576            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6577            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6578        } catch (ClassCastException e) {
6579        }
6580        return null;
6581    }
6582
6583    @Override
6584    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6585        if (!(pendingResult instanceof PendingIntentRecord)) {
6586            return null;
6587        }
6588        try {
6589            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6590            Intent intent = res.key.requestIntent;
6591            if (intent != null) {
6592                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6593                        || res.lastTagPrefix.equals(prefix))) {
6594                    return res.lastTag;
6595                }
6596                res.lastTagPrefix = prefix;
6597                StringBuilder sb = new StringBuilder(128);
6598                if (prefix != null) {
6599                    sb.append(prefix);
6600                }
6601                if (intent.getAction() != null) {
6602                    sb.append(intent.getAction());
6603                } else if (intent.getComponent() != null) {
6604                    intent.getComponent().appendShortString(sb);
6605                } else {
6606                    sb.append("?");
6607                }
6608                return res.lastTag = sb.toString();
6609            }
6610        } catch (ClassCastException e) {
6611        }
6612        return null;
6613    }
6614
6615    @Override
6616    public void setProcessLimit(int max) {
6617        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6618                "setProcessLimit()");
6619        synchronized (this) {
6620            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6621            mProcessLimitOverride = max;
6622        }
6623        trimApplications();
6624    }
6625
6626    @Override
6627    public int getProcessLimit() {
6628        synchronized (this) {
6629            return mProcessLimitOverride;
6630        }
6631    }
6632
6633    void foregroundTokenDied(ForegroundToken token) {
6634        synchronized (ActivityManagerService.this) {
6635            synchronized (mPidsSelfLocked) {
6636                ForegroundToken cur
6637                    = mForegroundProcesses.get(token.pid);
6638                if (cur != token) {
6639                    return;
6640                }
6641                mForegroundProcesses.remove(token.pid);
6642                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6643                if (pr == null) {
6644                    return;
6645                }
6646                pr.forcingToForeground = null;
6647                updateProcessForegroundLocked(pr, false, false);
6648            }
6649            updateOomAdjLocked();
6650        }
6651    }
6652
6653    @Override
6654    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6655        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6656                "setProcessForeground()");
6657        synchronized(this) {
6658            boolean changed = false;
6659
6660            synchronized (mPidsSelfLocked) {
6661                ProcessRecord pr = mPidsSelfLocked.get(pid);
6662                if (pr == null && isForeground) {
6663                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6664                    return;
6665                }
6666                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6667                if (oldToken != null) {
6668                    oldToken.token.unlinkToDeath(oldToken, 0);
6669                    mForegroundProcesses.remove(pid);
6670                    if (pr != null) {
6671                        pr.forcingToForeground = null;
6672                    }
6673                    changed = true;
6674                }
6675                if (isForeground && token != null) {
6676                    ForegroundToken newToken = new ForegroundToken() {
6677                        @Override
6678                        public void binderDied() {
6679                            foregroundTokenDied(this);
6680                        }
6681                    };
6682                    newToken.pid = pid;
6683                    newToken.token = token;
6684                    try {
6685                        token.linkToDeath(newToken, 0);
6686                        mForegroundProcesses.put(pid, newToken);
6687                        pr.forcingToForeground = token;
6688                        changed = true;
6689                    } catch (RemoteException e) {
6690                        // If the process died while doing this, we will later
6691                        // do the cleanup with the process death link.
6692                    }
6693                }
6694            }
6695
6696            if (changed) {
6697                updateOomAdjLocked();
6698            }
6699        }
6700    }
6701
6702    // =========================================================
6703    // PERMISSIONS
6704    // =========================================================
6705
6706    static class PermissionController extends IPermissionController.Stub {
6707        ActivityManagerService mActivityManagerService;
6708        PermissionController(ActivityManagerService activityManagerService) {
6709            mActivityManagerService = activityManagerService;
6710        }
6711
6712        @Override
6713        public boolean checkPermission(String permission, int pid, int uid) {
6714            return mActivityManagerService.checkPermission(permission, pid,
6715                    uid) == PackageManager.PERMISSION_GRANTED;
6716        }
6717    }
6718
6719    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6720        @Override
6721        public int checkComponentPermission(String permission, int pid, int uid,
6722                int owningUid, boolean exported) {
6723            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6724                    owningUid, exported);
6725        }
6726
6727        @Override
6728        public Object getAMSLock() {
6729            return ActivityManagerService.this;
6730        }
6731    }
6732
6733    /**
6734     * This can be called with or without the global lock held.
6735     */
6736    int checkComponentPermission(String permission, int pid, int uid,
6737            int owningUid, boolean exported) {
6738        if (pid == MY_PID) {
6739            return PackageManager.PERMISSION_GRANTED;
6740        }
6741        return ActivityManager.checkComponentPermission(permission, uid,
6742                owningUid, exported);
6743    }
6744
6745    /**
6746     * As the only public entry point for permissions checking, this method
6747     * can enforce the semantic that requesting a check on a null global
6748     * permission is automatically denied.  (Internally a null permission
6749     * string is used when calling {@link #checkComponentPermission} in cases
6750     * when only uid-based security is needed.)
6751     *
6752     * This can be called with or without the global lock held.
6753     */
6754    @Override
6755    public int checkPermission(String permission, int pid, int uid) {
6756        if (permission == null) {
6757            return PackageManager.PERMISSION_DENIED;
6758        }
6759        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6760    }
6761
6762    @Override
6763    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6764        if (permission == null) {
6765            return PackageManager.PERMISSION_DENIED;
6766        }
6767
6768        // We might be performing an operation on behalf of an indirect binder
6769        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6770        // client identity accordingly before proceeding.
6771        Identity tlsIdentity = sCallerIdentity.get();
6772        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6773            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6774                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6775            uid = tlsIdentity.uid;
6776            pid = tlsIdentity.pid;
6777        }
6778
6779        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6780    }
6781
6782    /**
6783     * Binder IPC calls go through the public entry point.
6784     * This can be called with or without the global lock held.
6785     */
6786    int checkCallingPermission(String permission) {
6787        return checkPermission(permission,
6788                Binder.getCallingPid(),
6789                UserHandle.getAppId(Binder.getCallingUid()));
6790    }
6791
6792    /**
6793     * This can be called with or without the global lock held.
6794     */
6795    void enforceCallingPermission(String permission, String func) {
6796        if (checkCallingPermission(permission)
6797                == PackageManager.PERMISSION_GRANTED) {
6798            return;
6799        }
6800
6801        String msg = "Permission Denial: " + func + " from pid="
6802                + Binder.getCallingPid()
6803                + ", uid=" + Binder.getCallingUid()
6804                + " requires " + permission;
6805        Slog.w(TAG, msg);
6806        throw new SecurityException(msg);
6807    }
6808
6809    /**
6810     * Determine if UID is holding permissions required to access {@link Uri} in
6811     * the given {@link ProviderInfo}. Final permission checking is always done
6812     * in {@link ContentProvider}.
6813     */
6814    private final boolean checkHoldingPermissionsLocked(
6815            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6816        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6817                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6818        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6819            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6820                    != PERMISSION_GRANTED) {
6821                return false;
6822            }
6823        }
6824        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6825    }
6826
6827    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6828            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6829        if (pi.applicationInfo.uid == uid) {
6830            return true;
6831        } else if (!pi.exported) {
6832            return false;
6833        }
6834
6835        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6836        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6837        try {
6838            // check if target holds top-level <provider> permissions
6839            if (!readMet && pi.readPermission != null && considerUidPermissions
6840                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6841                readMet = true;
6842            }
6843            if (!writeMet && pi.writePermission != null && considerUidPermissions
6844                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6845                writeMet = true;
6846            }
6847
6848            // track if unprotected read/write is allowed; any denied
6849            // <path-permission> below removes this ability
6850            boolean allowDefaultRead = pi.readPermission == null;
6851            boolean allowDefaultWrite = pi.writePermission == null;
6852
6853            // check if target holds any <path-permission> that match uri
6854            final PathPermission[] pps = pi.pathPermissions;
6855            if (pps != null) {
6856                final String path = grantUri.uri.getPath();
6857                int i = pps.length;
6858                while (i > 0 && (!readMet || !writeMet)) {
6859                    i--;
6860                    PathPermission pp = pps[i];
6861                    if (pp.match(path)) {
6862                        if (!readMet) {
6863                            final String pprperm = pp.getReadPermission();
6864                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6865                                    + pprperm + " for " + pp.getPath()
6866                                    + ": match=" + pp.match(path)
6867                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6868                            if (pprperm != null) {
6869                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6870                                        == PERMISSION_GRANTED) {
6871                                    readMet = true;
6872                                } else {
6873                                    allowDefaultRead = false;
6874                                }
6875                            }
6876                        }
6877                        if (!writeMet) {
6878                            final String ppwperm = pp.getWritePermission();
6879                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6880                                    + ppwperm + " for " + pp.getPath()
6881                                    + ": match=" + pp.match(path)
6882                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6883                            if (ppwperm != null) {
6884                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6885                                        == PERMISSION_GRANTED) {
6886                                    writeMet = true;
6887                                } else {
6888                                    allowDefaultWrite = false;
6889                                }
6890                            }
6891                        }
6892                    }
6893                }
6894            }
6895
6896            // grant unprotected <provider> read/write, if not blocked by
6897            // <path-permission> above
6898            if (allowDefaultRead) readMet = true;
6899            if (allowDefaultWrite) writeMet = true;
6900
6901        } catch (RemoteException e) {
6902            return false;
6903        }
6904
6905        return readMet && writeMet;
6906    }
6907
6908    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6909        ProviderInfo pi = null;
6910        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6911        if (cpr != null) {
6912            pi = cpr.info;
6913        } else {
6914            try {
6915                pi = AppGlobals.getPackageManager().resolveContentProvider(
6916                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6917            } catch (RemoteException ex) {
6918            }
6919        }
6920        return pi;
6921    }
6922
6923    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6924        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6925        if (targetUris != null) {
6926            return targetUris.get(grantUri);
6927        }
6928        return null;
6929    }
6930
6931    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6932            String targetPkg, int targetUid, GrantUri grantUri) {
6933        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6934        if (targetUris == null) {
6935            targetUris = Maps.newArrayMap();
6936            mGrantedUriPermissions.put(targetUid, targetUris);
6937        }
6938
6939        UriPermission perm = targetUris.get(grantUri);
6940        if (perm == null) {
6941            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6942            targetUris.put(grantUri, perm);
6943        }
6944
6945        return perm;
6946    }
6947
6948    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6949            final int modeFlags) {
6950        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6951        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6952                : UriPermission.STRENGTH_OWNED;
6953
6954        // Root gets to do everything.
6955        if (uid == 0) {
6956            return true;
6957        }
6958
6959        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6960        if (perms == null) return false;
6961
6962        // First look for exact match
6963        final UriPermission exactPerm = perms.get(grantUri);
6964        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6965            return true;
6966        }
6967
6968        // No exact match, look for prefixes
6969        final int N = perms.size();
6970        for (int i = 0; i < N; i++) {
6971            final UriPermission perm = perms.valueAt(i);
6972            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6973                    && perm.getStrength(modeFlags) >= minStrength) {
6974                return true;
6975            }
6976        }
6977
6978        return false;
6979    }
6980
6981    /**
6982     * @param uri This uri must NOT contain an embedded userId.
6983     * @param userId The userId in which the uri is to be resolved.
6984     */
6985    @Override
6986    public int checkUriPermission(Uri uri, int pid, int uid,
6987            final int modeFlags, int userId, IBinder callerToken) {
6988        enforceNotIsolatedCaller("checkUriPermission");
6989
6990        // Another redirected-binder-call permissions check as in
6991        // {@link checkPermissionWithToken}.
6992        Identity tlsIdentity = sCallerIdentity.get();
6993        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6994            uid = tlsIdentity.uid;
6995            pid = tlsIdentity.pid;
6996        }
6997
6998        // Our own process gets to do everything.
6999        if (pid == MY_PID) {
7000            return PackageManager.PERMISSION_GRANTED;
7001        }
7002        synchronized (this) {
7003            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7004                    ? PackageManager.PERMISSION_GRANTED
7005                    : PackageManager.PERMISSION_DENIED;
7006        }
7007    }
7008
7009    /**
7010     * Check if the targetPkg can be granted permission to access uri by
7011     * the callingUid using the given modeFlags.  Throws a security exception
7012     * if callingUid is not allowed to do this.  Returns the uid of the target
7013     * if the URI permission grant should be performed; returns -1 if it is not
7014     * needed (for example targetPkg already has permission to access the URI).
7015     * If you already know the uid of the target, you can supply it in
7016     * lastTargetUid else set that to -1.
7017     */
7018    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7019            final int modeFlags, int lastTargetUid) {
7020        if (!Intent.isAccessUriMode(modeFlags)) {
7021            return -1;
7022        }
7023
7024        if (targetPkg != null) {
7025            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7026                    "Checking grant " + targetPkg + " permission to " + grantUri);
7027        }
7028
7029        final IPackageManager pm = AppGlobals.getPackageManager();
7030
7031        // If this is not a content: uri, we can't do anything with it.
7032        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7033            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7034                    "Can't grant URI permission for non-content URI: " + grantUri);
7035            return -1;
7036        }
7037
7038        final String authority = grantUri.uri.getAuthority();
7039        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7040        if (pi == null) {
7041            Slog.w(TAG, "No content provider found for permission check: " +
7042                    grantUri.uri.toSafeString());
7043            return -1;
7044        }
7045
7046        int targetUid = lastTargetUid;
7047        if (targetUid < 0 && targetPkg != null) {
7048            try {
7049                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7050                if (targetUid < 0) {
7051                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7052                            "Can't grant URI permission no uid for: " + targetPkg);
7053                    return -1;
7054                }
7055            } catch (RemoteException ex) {
7056                return -1;
7057            }
7058        }
7059
7060        if (targetUid >= 0) {
7061            // First...  does the target actually need this permission?
7062            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7063                // No need to grant the target this permission.
7064                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7065                        "Target " + targetPkg + " already has full permission to " + grantUri);
7066                return -1;
7067            }
7068        } else {
7069            // First...  there is no target package, so can anyone access it?
7070            boolean allowed = pi.exported;
7071            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7072                if (pi.readPermission != null) {
7073                    allowed = false;
7074                }
7075            }
7076            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7077                if (pi.writePermission != null) {
7078                    allowed = false;
7079                }
7080            }
7081            if (allowed) {
7082                return -1;
7083            }
7084        }
7085
7086        /* There is a special cross user grant if:
7087         * - The target is on another user.
7088         * - Apps on the current user can access the uri without any uid permissions.
7089         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7090         * grant uri permissions.
7091         */
7092        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7093                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7094                modeFlags, false /*without considering the uid permissions*/);
7095
7096        // Second...  is the provider allowing granting of URI permissions?
7097        if (!specialCrossUserGrant) {
7098            if (!pi.grantUriPermissions) {
7099                throw new SecurityException("Provider " + pi.packageName
7100                        + "/" + pi.name
7101                        + " does not allow granting of Uri permissions (uri "
7102                        + grantUri + ")");
7103            }
7104            if (pi.uriPermissionPatterns != null) {
7105                final int N = pi.uriPermissionPatterns.length;
7106                boolean allowed = false;
7107                for (int i=0; i<N; i++) {
7108                    if (pi.uriPermissionPatterns[i] != null
7109                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7110                        allowed = true;
7111                        break;
7112                    }
7113                }
7114                if (!allowed) {
7115                    throw new SecurityException("Provider " + pi.packageName
7116                            + "/" + pi.name
7117                            + " does not allow granting of permission to path of Uri "
7118                            + grantUri);
7119                }
7120            }
7121        }
7122
7123        // Third...  does the caller itself have permission to access
7124        // this uri?
7125        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7126            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7127                // Require they hold a strong enough Uri permission
7128                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7129                    throw new SecurityException("Uid " + callingUid
7130                            + " does not have permission to uri " + grantUri);
7131                }
7132            }
7133        }
7134        return targetUid;
7135    }
7136
7137    /**
7138     * @param uri This uri must NOT contain an embedded userId.
7139     * @param userId The userId in which the uri is to be resolved.
7140     */
7141    @Override
7142    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7143            final int modeFlags, int userId) {
7144        enforceNotIsolatedCaller("checkGrantUriPermission");
7145        synchronized(this) {
7146            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7147                    new GrantUri(userId, uri, false), modeFlags, -1);
7148        }
7149    }
7150
7151    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7152            final int modeFlags, UriPermissionOwner owner) {
7153        if (!Intent.isAccessUriMode(modeFlags)) {
7154            return;
7155        }
7156
7157        // So here we are: the caller has the assumed permission
7158        // to the uri, and the target doesn't.  Let's now give this to
7159        // the target.
7160
7161        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7162                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7163
7164        final String authority = grantUri.uri.getAuthority();
7165        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7166        if (pi == null) {
7167            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7168            return;
7169        }
7170
7171        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7172            grantUri.prefix = true;
7173        }
7174        final UriPermission perm = findOrCreateUriPermissionLocked(
7175                pi.packageName, targetPkg, targetUid, grantUri);
7176        perm.grantModes(modeFlags, owner);
7177    }
7178
7179    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7180            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7181        if (targetPkg == null) {
7182            throw new NullPointerException("targetPkg");
7183        }
7184        int targetUid;
7185        final IPackageManager pm = AppGlobals.getPackageManager();
7186        try {
7187            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7188        } catch (RemoteException ex) {
7189            return;
7190        }
7191
7192        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7193                targetUid);
7194        if (targetUid < 0) {
7195            return;
7196        }
7197
7198        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7199                owner);
7200    }
7201
7202    static class NeededUriGrants extends ArrayList<GrantUri> {
7203        final String targetPkg;
7204        final int targetUid;
7205        final int flags;
7206
7207        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7208            this.targetPkg = targetPkg;
7209            this.targetUid = targetUid;
7210            this.flags = flags;
7211        }
7212    }
7213
7214    /**
7215     * Like checkGrantUriPermissionLocked, but takes an Intent.
7216     */
7217    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7218            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7219        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7220                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7221                + " clip=" + (intent != null ? intent.getClipData() : null)
7222                + " from " + intent + "; flags=0x"
7223                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7224
7225        if (targetPkg == null) {
7226            throw new NullPointerException("targetPkg");
7227        }
7228
7229        if (intent == null) {
7230            return null;
7231        }
7232        Uri data = intent.getData();
7233        ClipData clip = intent.getClipData();
7234        if (data == null && clip == null) {
7235            return null;
7236        }
7237        // Default userId for uris in the intent (if they don't specify it themselves)
7238        int contentUserHint = intent.getContentUserHint();
7239        if (contentUserHint == UserHandle.USER_CURRENT) {
7240            contentUserHint = UserHandle.getUserId(callingUid);
7241        }
7242        final IPackageManager pm = AppGlobals.getPackageManager();
7243        int targetUid;
7244        if (needed != null) {
7245            targetUid = needed.targetUid;
7246        } else {
7247            try {
7248                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7249            } catch (RemoteException ex) {
7250                return null;
7251            }
7252            if (targetUid < 0) {
7253                if (DEBUG_URI_PERMISSION) {
7254                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7255                            + " on user " + targetUserId);
7256                }
7257                return null;
7258            }
7259        }
7260        if (data != null) {
7261            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7262            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7263                    targetUid);
7264            if (targetUid > 0) {
7265                if (needed == null) {
7266                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7267                }
7268                needed.add(grantUri);
7269            }
7270        }
7271        if (clip != null) {
7272            for (int i=0; i<clip.getItemCount(); i++) {
7273                Uri uri = clip.getItemAt(i).getUri();
7274                if (uri != null) {
7275                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7276                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7277                            targetUid);
7278                    if (targetUid > 0) {
7279                        if (needed == null) {
7280                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7281                        }
7282                        needed.add(grantUri);
7283                    }
7284                } else {
7285                    Intent clipIntent = clip.getItemAt(i).getIntent();
7286                    if (clipIntent != null) {
7287                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7288                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7289                        if (newNeeded != null) {
7290                            needed = newNeeded;
7291                        }
7292                    }
7293                }
7294            }
7295        }
7296
7297        return needed;
7298    }
7299
7300    /**
7301     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7302     */
7303    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7304            UriPermissionOwner owner) {
7305        if (needed != null) {
7306            for (int i=0; i<needed.size(); i++) {
7307                GrantUri grantUri = needed.get(i);
7308                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7309                        grantUri, needed.flags, owner);
7310            }
7311        }
7312    }
7313
7314    void grantUriPermissionFromIntentLocked(int callingUid,
7315            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7316        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7317                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7318        if (needed == null) {
7319            return;
7320        }
7321
7322        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7323    }
7324
7325    /**
7326     * @param uri This uri must NOT contain an embedded userId.
7327     * @param userId The userId in which the uri is to be resolved.
7328     */
7329    @Override
7330    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7331            final int modeFlags, int userId) {
7332        enforceNotIsolatedCaller("grantUriPermission");
7333        GrantUri grantUri = new GrantUri(userId, uri, false);
7334        synchronized(this) {
7335            final ProcessRecord r = getRecordForAppLocked(caller);
7336            if (r == null) {
7337                throw new SecurityException("Unable to find app for caller "
7338                        + caller
7339                        + " when granting permission to uri " + grantUri);
7340            }
7341            if (targetPkg == null) {
7342                throw new IllegalArgumentException("null target");
7343            }
7344            if (grantUri == null) {
7345                throw new IllegalArgumentException("null uri");
7346            }
7347
7348            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7349                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7350                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7351                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7352
7353            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7354                    UserHandle.getUserId(r.uid));
7355        }
7356    }
7357
7358    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7359        if (perm.modeFlags == 0) {
7360            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7361                    perm.targetUid);
7362            if (perms != null) {
7363                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7364                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7365
7366                perms.remove(perm.uri);
7367                if (perms.isEmpty()) {
7368                    mGrantedUriPermissions.remove(perm.targetUid);
7369                }
7370            }
7371        }
7372    }
7373
7374    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7375        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7376
7377        final IPackageManager pm = AppGlobals.getPackageManager();
7378        final String authority = grantUri.uri.getAuthority();
7379        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7380        if (pi == null) {
7381            Slog.w(TAG, "No content provider found for permission revoke: "
7382                    + grantUri.toSafeString());
7383            return;
7384        }
7385
7386        // Does the caller have this permission on the URI?
7387        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7388            // If they don't have direct access to the URI, then revoke any
7389            // ownerless URI permissions that have been granted to them.
7390            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7391            if (perms != null) {
7392                boolean persistChanged = false;
7393                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7394                    final UriPermission perm = it.next();
7395                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7396                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7397                        if (DEBUG_URI_PERMISSION)
7398                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7399                                    " permission to " + perm.uri);
7400                        persistChanged |= perm.revokeModes(
7401                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7402                        if (perm.modeFlags == 0) {
7403                            it.remove();
7404                        }
7405                    }
7406                }
7407                if (perms.isEmpty()) {
7408                    mGrantedUriPermissions.remove(callingUid);
7409                }
7410                if (persistChanged) {
7411                    schedulePersistUriGrants();
7412                }
7413            }
7414            return;
7415        }
7416
7417        boolean persistChanged = false;
7418
7419        // Go through all of the permissions and remove any that match.
7420        int N = mGrantedUriPermissions.size();
7421        for (int i = 0; i < N; i++) {
7422            final int targetUid = mGrantedUriPermissions.keyAt(i);
7423            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7424
7425            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7426                final UriPermission perm = it.next();
7427                if (perm.uri.sourceUserId == grantUri.sourceUserId
7428                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7429                    if (DEBUG_URI_PERMISSION)
7430                        Slog.v(TAG,
7431                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7432                    persistChanged |= perm.revokeModes(
7433                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7434                    if (perm.modeFlags == 0) {
7435                        it.remove();
7436                    }
7437                }
7438            }
7439
7440            if (perms.isEmpty()) {
7441                mGrantedUriPermissions.remove(targetUid);
7442                N--;
7443                i--;
7444            }
7445        }
7446
7447        if (persistChanged) {
7448            schedulePersistUriGrants();
7449        }
7450    }
7451
7452    /**
7453     * @param uri This uri must NOT contain an embedded userId.
7454     * @param userId The userId in which the uri is to be resolved.
7455     */
7456    @Override
7457    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7458            int userId) {
7459        enforceNotIsolatedCaller("revokeUriPermission");
7460        synchronized(this) {
7461            final ProcessRecord r = getRecordForAppLocked(caller);
7462            if (r == null) {
7463                throw new SecurityException("Unable to find app for caller "
7464                        + caller
7465                        + " when revoking permission to uri " + uri);
7466            }
7467            if (uri == null) {
7468                Slog.w(TAG, "revokeUriPermission: null uri");
7469                return;
7470            }
7471
7472            if (!Intent.isAccessUriMode(modeFlags)) {
7473                return;
7474            }
7475
7476            final IPackageManager pm = AppGlobals.getPackageManager();
7477            final String authority = uri.getAuthority();
7478            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7479            if (pi == null) {
7480                Slog.w(TAG, "No content provider found for permission revoke: "
7481                        + uri.toSafeString());
7482                return;
7483            }
7484
7485            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7486        }
7487    }
7488
7489    /**
7490     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7491     * given package.
7492     *
7493     * @param packageName Package name to match, or {@code null} to apply to all
7494     *            packages.
7495     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7496     *            to all users.
7497     * @param persistable If persistable grants should be removed.
7498     */
7499    private void removeUriPermissionsForPackageLocked(
7500            String packageName, int userHandle, boolean persistable) {
7501        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7502            throw new IllegalArgumentException("Must narrow by either package or user");
7503        }
7504
7505        boolean persistChanged = false;
7506
7507        int N = mGrantedUriPermissions.size();
7508        for (int i = 0; i < N; i++) {
7509            final int targetUid = mGrantedUriPermissions.keyAt(i);
7510            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7511
7512            // Only inspect grants matching user
7513            if (userHandle == UserHandle.USER_ALL
7514                    || userHandle == UserHandle.getUserId(targetUid)) {
7515                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7516                    final UriPermission perm = it.next();
7517
7518                    // Only inspect grants matching package
7519                    if (packageName == null || perm.sourcePkg.equals(packageName)
7520                            || perm.targetPkg.equals(packageName)) {
7521                        persistChanged |= perm.revokeModes(persistable
7522                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7523
7524                        // Only remove when no modes remain; any persisted grants
7525                        // will keep this alive.
7526                        if (perm.modeFlags == 0) {
7527                            it.remove();
7528                        }
7529                    }
7530                }
7531
7532                if (perms.isEmpty()) {
7533                    mGrantedUriPermissions.remove(targetUid);
7534                    N--;
7535                    i--;
7536                }
7537            }
7538        }
7539
7540        if (persistChanged) {
7541            schedulePersistUriGrants();
7542        }
7543    }
7544
7545    @Override
7546    public IBinder newUriPermissionOwner(String name) {
7547        enforceNotIsolatedCaller("newUriPermissionOwner");
7548        synchronized(this) {
7549            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7550            return owner.getExternalTokenLocked();
7551        }
7552    }
7553
7554    /**
7555     * @param uri This uri must NOT contain an embedded userId.
7556     * @param sourceUserId The userId in which the uri is to be resolved.
7557     * @param targetUserId The userId of the app that receives the grant.
7558     */
7559    @Override
7560    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7561            final int modeFlags, int sourceUserId, int targetUserId) {
7562        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7563                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7564        synchronized(this) {
7565            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7566            if (owner == null) {
7567                throw new IllegalArgumentException("Unknown owner: " + token);
7568            }
7569            if (fromUid != Binder.getCallingUid()) {
7570                if (Binder.getCallingUid() != Process.myUid()) {
7571                    // Only system code can grant URI permissions on behalf
7572                    // of other users.
7573                    throw new SecurityException("nice try");
7574                }
7575            }
7576            if (targetPkg == null) {
7577                throw new IllegalArgumentException("null target");
7578            }
7579            if (uri == null) {
7580                throw new IllegalArgumentException("null uri");
7581            }
7582
7583            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7584                    modeFlags, owner, targetUserId);
7585        }
7586    }
7587
7588    /**
7589     * @param uri This uri must NOT contain an embedded userId.
7590     * @param userId The userId in which the uri is to be resolved.
7591     */
7592    @Override
7593    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7594        synchronized(this) {
7595            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7596            if (owner == null) {
7597                throw new IllegalArgumentException("Unknown owner: " + token);
7598            }
7599
7600            if (uri == null) {
7601                owner.removeUriPermissionsLocked(mode);
7602            } else {
7603                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7604            }
7605        }
7606    }
7607
7608    private void schedulePersistUriGrants() {
7609        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7610            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7611                    10 * DateUtils.SECOND_IN_MILLIS);
7612        }
7613    }
7614
7615    private void writeGrantedUriPermissions() {
7616        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7617
7618        // Snapshot permissions so we can persist without lock
7619        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7620        synchronized (this) {
7621            final int size = mGrantedUriPermissions.size();
7622            for (int i = 0; i < size; i++) {
7623                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7624                for (UriPermission perm : perms.values()) {
7625                    if (perm.persistedModeFlags != 0) {
7626                        persist.add(perm.snapshot());
7627                    }
7628                }
7629            }
7630        }
7631
7632        FileOutputStream fos = null;
7633        try {
7634            fos = mGrantFile.startWrite();
7635
7636            XmlSerializer out = new FastXmlSerializer();
7637            out.setOutput(fos, "utf-8");
7638            out.startDocument(null, true);
7639            out.startTag(null, TAG_URI_GRANTS);
7640            for (UriPermission.Snapshot perm : persist) {
7641                out.startTag(null, TAG_URI_GRANT);
7642                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7643                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7644                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7645                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7646                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7647                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7648                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7649                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7650                out.endTag(null, TAG_URI_GRANT);
7651            }
7652            out.endTag(null, TAG_URI_GRANTS);
7653            out.endDocument();
7654
7655            mGrantFile.finishWrite(fos);
7656        } catch (IOException e) {
7657            if (fos != null) {
7658                mGrantFile.failWrite(fos);
7659            }
7660        }
7661    }
7662
7663    private void readGrantedUriPermissionsLocked() {
7664        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7665
7666        final long now = System.currentTimeMillis();
7667
7668        FileInputStream fis = null;
7669        try {
7670            fis = mGrantFile.openRead();
7671            final XmlPullParser in = Xml.newPullParser();
7672            in.setInput(fis, null);
7673
7674            int type;
7675            while ((type = in.next()) != END_DOCUMENT) {
7676                final String tag = in.getName();
7677                if (type == START_TAG) {
7678                    if (TAG_URI_GRANT.equals(tag)) {
7679                        final int sourceUserId;
7680                        final int targetUserId;
7681                        final int userHandle = readIntAttribute(in,
7682                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7683                        if (userHandle != UserHandle.USER_NULL) {
7684                            // For backwards compatibility.
7685                            sourceUserId = userHandle;
7686                            targetUserId = userHandle;
7687                        } else {
7688                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7689                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7690                        }
7691                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7692                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7693                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7694                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7695                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7696                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7697
7698                        // Sanity check that provider still belongs to source package
7699                        final ProviderInfo pi = getProviderInfoLocked(
7700                                uri.getAuthority(), sourceUserId);
7701                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7702                            int targetUid = -1;
7703                            try {
7704                                targetUid = AppGlobals.getPackageManager()
7705                                        .getPackageUid(targetPkg, targetUserId);
7706                            } catch (RemoteException e) {
7707                            }
7708                            if (targetUid != -1) {
7709                                final UriPermission perm = findOrCreateUriPermissionLocked(
7710                                        sourcePkg, targetPkg, targetUid,
7711                                        new GrantUri(sourceUserId, uri, prefix));
7712                                perm.initPersistedModes(modeFlags, createdTime);
7713                            }
7714                        } else {
7715                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7716                                    + " but instead found " + pi);
7717                        }
7718                    }
7719                }
7720            }
7721        } catch (FileNotFoundException e) {
7722            // Missing grants is okay
7723        } catch (IOException e) {
7724            Slog.wtf(TAG, "Failed reading Uri grants", e);
7725        } catch (XmlPullParserException e) {
7726            Slog.wtf(TAG, "Failed reading Uri grants", e);
7727        } finally {
7728            IoUtils.closeQuietly(fis);
7729        }
7730    }
7731
7732    /**
7733     * @param uri This uri must NOT contain an embedded userId.
7734     * @param userId The userId in which the uri is to be resolved.
7735     */
7736    @Override
7737    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7738        enforceNotIsolatedCaller("takePersistableUriPermission");
7739
7740        Preconditions.checkFlagsArgument(modeFlags,
7741                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7742
7743        synchronized (this) {
7744            final int callingUid = Binder.getCallingUid();
7745            boolean persistChanged = false;
7746            GrantUri grantUri = new GrantUri(userId, uri, false);
7747
7748            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7749                    new GrantUri(userId, uri, false));
7750            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7751                    new GrantUri(userId, uri, true));
7752
7753            final boolean exactValid = (exactPerm != null)
7754                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7755            final boolean prefixValid = (prefixPerm != null)
7756                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7757
7758            if (!(exactValid || prefixValid)) {
7759                throw new SecurityException("No persistable permission grants found for UID "
7760                        + callingUid + " and Uri " + grantUri.toSafeString());
7761            }
7762
7763            if (exactValid) {
7764                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7765            }
7766            if (prefixValid) {
7767                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7768            }
7769
7770            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7771
7772            if (persistChanged) {
7773                schedulePersistUriGrants();
7774            }
7775        }
7776    }
7777
7778    /**
7779     * @param uri This uri must NOT contain an embedded userId.
7780     * @param userId The userId in which the uri is to be resolved.
7781     */
7782    @Override
7783    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7784        enforceNotIsolatedCaller("releasePersistableUriPermission");
7785
7786        Preconditions.checkFlagsArgument(modeFlags,
7787                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7788
7789        synchronized (this) {
7790            final int callingUid = Binder.getCallingUid();
7791            boolean persistChanged = false;
7792
7793            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7794                    new GrantUri(userId, uri, false));
7795            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7796                    new GrantUri(userId, uri, true));
7797            if (exactPerm == null && prefixPerm == null) {
7798                throw new SecurityException("No permission grants found for UID " + callingUid
7799                        + " and Uri " + uri.toSafeString());
7800            }
7801
7802            if (exactPerm != null) {
7803                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7804                removeUriPermissionIfNeededLocked(exactPerm);
7805            }
7806            if (prefixPerm != null) {
7807                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7808                removeUriPermissionIfNeededLocked(prefixPerm);
7809            }
7810
7811            if (persistChanged) {
7812                schedulePersistUriGrants();
7813            }
7814        }
7815    }
7816
7817    /**
7818     * Prune any older {@link UriPermission} for the given UID until outstanding
7819     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7820     *
7821     * @return if any mutations occured that require persisting.
7822     */
7823    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7824        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7825        if (perms == null) return false;
7826        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7827
7828        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7829        for (UriPermission perm : perms.values()) {
7830            if (perm.persistedModeFlags != 0) {
7831                persisted.add(perm);
7832            }
7833        }
7834
7835        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7836        if (trimCount <= 0) return false;
7837
7838        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7839        for (int i = 0; i < trimCount; i++) {
7840            final UriPermission perm = persisted.get(i);
7841
7842            if (DEBUG_URI_PERMISSION) {
7843                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7844            }
7845
7846            perm.releasePersistableModes(~0);
7847            removeUriPermissionIfNeededLocked(perm);
7848        }
7849
7850        return true;
7851    }
7852
7853    @Override
7854    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7855            String packageName, boolean incoming) {
7856        enforceNotIsolatedCaller("getPersistedUriPermissions");
7857        Preconditions.checkNotNull(packageName, "packageName");
7858
7859        final int callingUid = Binder.getCallingUid();
7860        final IPackageManager pm = AppGlobals.getPackageManager();
7861        try {
7862            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7863            if (packageUid != callingUid) {
7864                throw new SecurityException(
7865                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7866            }
7867        } catch (RemoteException e) {
7868            throw new SecurityException("Failed to verify package name ownership");
7869        }
7870
7871        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7872        synchronized (this) {
7873            if (incoming) {
7874                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7875                        callingUid);
7876                if (perms == null) {
7877                    Slog.w(TAG, "No permission grants found for " + packageName);
7878                } else {
7879                    for (UriPermission perm : perms.values()) {
7880                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7881                            result.add(perm.buildPersistedPublicApiObject());
7882                        }
7883                    }
7884                }
7885            } else {
7886                final int size = mGrantedUriPermissions.size();
7887                for (int i = 0; i < size; i++) {
7888                    final ArrayMap<GrantUri, UriPermission> perms =
7889                            mGrantedUriPermissions.valueAt(i);
7890                    for (UriPermission perm : perms.values()) {
7891                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7892                            result.add(perm.buildPersistedPublicApiObject());
7893                        }
7894                    }
7895                }
7896            }
7897        }
7898        return new ParceledListSlice<android.content.UriPermission>(result);
7899    }
7900
7901    @Override
7902    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7903        synchronized (this) {
7904            ProcessRecord app =
7905                who != null ? getRecordForAppLocked(who) : null;
7906            if (app == null) return;
7907
7908            Message msg = Message.obtain();
7909            msg.what = WAIT_FOR_DEBUGGER_MSG;
7910            msg.obj = app;
7911            msg.arg1 = waiting ? 1 : 0;
7912            mHandler.sendMessage(msg);
7913        }
7914    }
7915
7916    @Override
7917    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7918        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7919        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7920        outInfo.availMem = Process.getFreeMemory();
7921        outInfo.totalMem = Process.getTotalMemory();
7922        outInfo.threshold = homeAppMem;
7923        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7924        outInfo.hiddenAppThreshold = cachedAppMem;
7925        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7926                ProcessList.SERVICE_ADJ);
7927        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7928                ProcessList.VISIBLE_APP_ADJ);
7929        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7930                ProcessList.FOREGROUND_APP_ADJ);
7931    }
7932
7933    // =========================================================
7934    // TASK MANAGEMENT
7935    // =========================================================
7936
7937    @Override
7938    public List<IAppTask> getAppTasks(String callingPackage) {
7939        int callingUid = Binder.getCallingUid();
7940        long ident = Binder.clearCallingIdentity();
7941
7942        synchronized(this) {
7943            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7944            try {
7945                if (localLOGV) Slog.v(TAG, "getAppTasks");
7946
7947                final int N = mRecentTasks.size();
7948                for (int i = 0; i < N; i++) {
7949                    TaskRecord tr = mRecentTasks.get(i);
7950                    // Skip tasks that do not match the caller.  We don't need to verify
7951                    // callingPackage, because we are also limiting to callingUid and know
7952                    // that will limit to the correct security sandbox.
7953                    if (tr.effectiveUid != callingUid) {
7954                        continue;
7955                    }
7956                    Intent intent = tr.getBaseIntent();
7957                    if (intent == null ||
7958                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7959                        continue;
7960                    }
7961                    ActivityManager.RecentTaskInfo taskInfo =
7962                            createRecentTaskInfoFromTaskRecord(tr);
7963                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7964                    list.add(taskImpl);
7965                }
7966            } finally {
7967                Binder.restoreCallingIdentity(ident);
7968            }
7969            return list;
7970        }
7971    }
7972
7973    @Override
7974    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7975        final int callingUid = Binder.getCallingUid();
7976        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7977
7978        synchronized(this) {
7979            if (localLOGV) Slog.v(
7980                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7981
7982            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
7983                    callingUid);
7984
7985            // TODO: Improve with MRU list from all ActivityStacks.
7986            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7987        }
7988
7989        return list;
7990    }
7991
7992    TaskRecord getMostRecentTask() {
7993        return mRecentTasks.get(0);
7994    }
7995
7996    /**
7997     * Creates a new RecentTaskInfo from a TaskRecord.
7998     */
7999    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8000        // Update the task description to reflect any changes in the task stack
8001        tr.updateTaskDescription();
8002
8003        // Compose the recent task info
8004        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8005        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8006        rti.persistentId = tr.taskId;
8007        rti.baseIntent = new Intent(tr.getBaseIntent());
8008        rti.origActivity = tr.origActivity;
8009        rti.description = tr.lastDescription;
8010        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8011        rti.userId = tr.userId;
8012        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8013        rti.firstActiveTime = tr.firstActiveTime;
8014        rti.lastActiveTime = tr.lastActiveTime;
8015        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8016        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8017        return rti;
8018    }
8019
8020    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8021        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8022                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8023        if (!allowed) {
8024            if (checkPermission(android.Manifest.permission.GET_TASKS,
8025                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8026                // Temporary compatibility: some existing apps on the system image may
8027                // still be requesting the old permission and not switched to the new
8028                // one; if so, we'll still allow them full access.  This means we need
8029                // to see if they are holding the old permission and are a system app.
8030                try {
8031                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8032                        allowed = true;
8033                        Slog.w(TAG, caller + ": caller " + callingUid
8034                                + " is using old GET_TASKS but privileged; allowing");
8035                    }
8036                } catch (RemoteException e) {
8037                }
8038            }
8039        }
8040        if (!allowed) {
8041            Slog.w(TAG, caller + ": caller " + callingUid
8042                    + " does not hold GET_TASKS; limiting output");
8043        }
8044        return allowed;
8045    }
8046
8047    @Override
8048    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8049        final int callingUid = Binder.getCallingUid();
8050        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8051                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8052
8053        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8054        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8055        synchronized (this) {
8056            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8057                    callingUid);
8058            final boolean detailed = checkCallingPermission(
8059                    android.Manifest.permission.GET_DETAILED_TASKS)
8060                    == PackageManager.PERMISSION_GRANTED;
8061
8062            final int N = mRecentTasks.size();
8063            ArrayList<ActivityManager.RecentTaskInfo> res
8064                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8065                            maxNum < N ? maxNum : N);
8066
8067            final Set<Integer> includedUsers;
8068            if (includeProfiles) {
8069                includedUsers = getProfileIdsLocked(userId);
8070            } else {
8071                includedUsers = new HashSet<Integer>();
8072            }
8073            includedUsers.add(Integer.valueOf(userId));
8074
8075            for (int i=0; i<N && maxNum > 0; i++) {
8076                TaskRecord tr = mRecentTasks.get(i);
8077                // Only add calling user or related users recent tasks
8078                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8079                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8080                    continue;
8081                }
8082
8083                // Return the entry if desired by the caller.  We always return
8084                // the first entry, because callers always expect this to be the
8085                // foreground app.  We may filter others if the caller has
8086                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8087                // we should exclude the entry.
8088
8089                if (i == 0
8090                        || withExcluded
8091                        || (tr.intent == null)
8092                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8093                                == 0)) {
8094                    if (!allowed) {
8095                        // If the caller doesn't have the GET_TASKS permission, then only
8096                        // allow them to see a small subset of tasks -- their own and home.
8097                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8098                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8099                            continue;
8100                        }
8101                    }
8102                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8103                        if (tr.stack != null && tr.stack.isHomeStack()) {
8104                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8105                            continue;
8106                        }
8107                    }
8108                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8109                        // Don't include auto remove tasks that are finished or finishing.
8110                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8111                                + tr);
8112                        continue;
8113                    }
8114                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8115                            && !tr.isAvailable) {
8116                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8117                        continue;
8118                    }
8119
8120                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8121                    if (!detailed) {
8122                        rti.baseIntent.replaceExtras((Bundle)null);
8123                    }
8124
8125                    res.add(rti);
8126                    maxNum--;
8127                }
8128            }
8129            return res;
8130        }
8131    }
8132
8133    private TaskRecord taskForIdLocked(int id) {
8134        final TaskRecord task = recentTaskForIdLocked(id);
8135        if (task != null) {
8136            return task;
8137        }
8138
8139        // Don't give up. Sometimes it just hasn't made it to recents yet.
8140        return mStackSupervisor.anyTaskForIdLocked(id);
8141    }
8142
8143    private TaskRecord recentTaskForIdLocked(int id) {
8144        final int N = mRecentTasks.size();
8145            for (int i=0; i<N; i++) {
8146                TaskRecord tr = mRecentTasks.get(i);
8147                if (tr.taskId == id) {
8148                    return tr;
8149                }
8150            }
8151            return null;
8152    }
8153
8154    @Override
8155    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8156        synchronized (this) {
8157            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8158                    "getTaskThumbnail()");
8159            TaskRecord tr = recentTaskForIdLocked(id);
8160            if (tr != null) {
8161                return tr.getTaskThumbnailLocked();
8162            }
8163        }
8164        return null;
8165    }
8166
8167    @Override
8168    public int addAppTask(IBinder activityToken, Intent intent,
8169            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8170        final int callingUid = Binder.getCallingUid();
8171        final long callingIdent = Binder.clearCallingIdentity();
8172
8173        try {
8174            synchronized (this) {
8175                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8176                if (r == null) {
8177                    throw new IllegalArgumentException("Activity does not exist; token="
8178                            + activityToken);
8179                }
8180                ComponentName comp = intent.getComponent();
8181                if (comp == null) {
8182                    throw new IllegalArgumentException("Intent " + intent
8183                            + " must specify explicit component");
8184                }
8185                if (thumbnail.getWidth() != mThumbnailWidth
8186                        || thumbnail.getHeight() != mThumbnailHeight) {
8187                    throw new IllegalArgumentException("Bad thumbnail size: got "
8188                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8189                            + mThumbnailWidth + "x" + mThumbnailHeight);
8190                }
8191                if (intent.getSelector() != null) {
8192                    intent.setSelector(null);
8193                }
8194                if (intent.getSourceBounds() != null) {
8195                    intent.setSourceBounds(null);
8196                }
8197                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8198                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8199                        // The caller has added this as an auto-remove task...  that makes no
8200                        // sense, so turn off auto-remove.
8201                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8202                    }
8203                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8204                    // Must be a new task.
8205                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8206                }
8207                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8208                    mLastAddedTaskActivity = null;
8209                }
8210                ActivityInfo ainfo = mLastAddedTaskActivity;
8211                if (ainfo == null) {
8212                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8213                            comp, 0, UserHandle.getUserId(callingUid));
8214                    if (ainfo.applicationInfo.uid != callingUid) {
8215                        throw new SecurityException(
8216                                "Can't add task for another application: target uid="
8217                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8218                    }
8219                }
8220
8221                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8222                        intent, description);
8223
8224                int trimIdx = trimRecentsForTask(task, false);
8225                if (trimIdx >= 0) {
8226                    // If this would have caused a trim, then we'll abort because that
8227                    // means it would be added at the end of the list but then just removed.
8228                    return -1;
8229                }
8230
8231                final int N = mRecentTasks.size();
8232                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8233                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8234                    tr.removedFromRecents(mTaskPersister);
8235                }
8236
8237                task.inRecents = true;
8238                mRecentTasks.add(task);
8239                r.task.stack.addTask(task, false, false);
8240
8241                task.setLastThumbnail(thumbnail);
8242                task.freeLastThumbnail();
8243
8244                return task.taskId;
8245            }
8246        } finally {
8247            Binder.restoreCallingIdentity(callingIdent);
8248        }
8249    }
8250
8251    @Override
8252    public Point getAppTaskThumbnailSize() {
8253        synchronized (this) {
8254            return new Point(mThumbnailWidth,  mThumbnailHeight);
8255        }
8256    }
8257
8258    @Override
8259    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8260        synchronized (this) {
8261            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8262            if (r != null) {
8263                r.setTaskDescription(td);
8264                r.task.updateTaskDescription();
8265            }
8266        }
8267    }
8268
8269    @Override
8270    public Bitmap getTaskDescriptionIcon(String filename) {
8271        if (!FileUtils.isValidExtFilename(filename)
8272                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8273            throw new IllegalArgumentException("Bad filename: " + filename);
8274        }
8275        return mTaskPersister.getTaskDescriptionIcon(filename);
8276    }
8277
8278    @Override
8279    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8280            throws RemoteException {
8281        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8282                opts.getCustomInPlaceResId() == 0) {
8283            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8284                    "with valid animation");
8285        }
8286        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8287        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8288                opts.getCustomInPlaceResId());
8289        mWindowManager.executeAppTransition();
8290    }
8291
8292    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8293        mRecentTasks.remove(tr);
8294        tr.removedFromRecents(mTaskPersister);
8295        ComponentName component = tr.getBaseIntent().getComponent();
8296        if (component == null) {
8297            Slog.w(TAG, "No component for base intent of task: " + tr);
8298            return;
8299        }
8300
8301        if (!killProcess) {
8302            return;
8303        }
8304
8305        // Determine if the process(es) for this task should be killed.
8306        final String pkg = component.getPackageName();
8307        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8308        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8309        for (int i = 0; i < pmap.size(); i++) {
8310
8311            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8312            for (int j = 0; j < uids.size(); j++) {
8313                ProcessRecord proc = uids.valueAt(j);
8314                if (proc.userId != tr.userId) {
8315                    // Don't kill process for a different user.
8316                    continue;
8317                }
8318                if (proc == mHomeProcess) {
8319                    // Don't kill the home process along with tasks from the same package.
8320                    continue;
8321                }
8322                if (!proc.pkgList.containsKey(pkg)) {
8323                    // Don't kill process that is not associated with this task.
8324                    continue;
8325                }
8326
8327                for (int k = 0; k < proc.activities.size(); k++) {
8328                    TaskRecord otherTask = proc.activities.get(k).task;
8329                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8330                        // Don't kill process(es) that has an activity in a different task that is
8331                        // also in recents.
8332                        return;
8333                    }
8334                }
8335
8336                // Add process to kill list.
8337                procsToKill.add(proc);
8338            }
8339        }
8340
8341        // Find any running services associated with this app and stop if needed.
8342        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8343
8344        // Kill the running processes.
8345        for (int i = 0; i < procsToKill.size(); i++) {
8346            ProcessRecord pr = procsToKill.get(i);
8347            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8348                pr.kill("remove task", true);
8349            } else {
8350                pr.waitingToKill = "remove task";
8351            }
8352        }
8353    }
8354
8355    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8356        // Remove all tasks with activities in the specified package from the list of recent tasks
8357        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8358            TaskRecord tr = mRecentTasks.get(i);
8359            if (tr.userId != userId) continue;
8360
8361            ComponentName cn = tr.intent.getComponent();
8362            if (cn != null && cn.getPackageName().equals(packageName)) {
8363                // If the package name matches, remove the task.
8364                removeTaskByIdLocked(tr.taskId, true);
8365            }
8366        }
8367    }
8368
8369    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8370        final IPackageManager pm = AppGlobals.getPackageManager();
8371        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8372
8373        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8374            TaskRecord tr = mRecentTasks.get(i);
8375            if (tr.userId != userId) continue;
8376
8377            ComponentName cn = tr.intent.getComponent();
8378            if (cn != null && cn.getPackageName().equals(packageName)) {
8379                // Skip if component still exists in the package.
8380                if (componentsKnownToExist.contains(cn)) continue;
8381
8382                try {
8383                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8384                    if (info != null) {
8385                        componentsKnownToExist.add(cn);
8386                    } else {
8387                        removeTaskByIdLocked(tr.taskId, false);
8388                    }
8389                } catch (RemoteException e) {
8390                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8391                }
8392            }
8393        }
8394    }
8395
8396    /**
8397     * Removes the task with the specified task id.
8398     *
8399     * @param taskId Identifier of the task to be removed.
8400     * @param killProcess Kill any process associated with the task if possible.
8401     * @return Returns true if the given task was found and removed.
8402     */
8403    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8404        TaskRecord tr = taskForIdLocked(taskId);
8405        if (tr != null) {
8406            tr.removeTaskActivitiesLocked();
8407            cleanUpRemovedTaskLocked(tr, killProcess);
8408            if (tr.isPersistable) {
8409                notifyTaskPersisterLocked(null, true);
8410            }
8411            return true;
8412        }
8413        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8414        return false;
8415    }
8416
8417    @Override
8418    public boolean removeTask(int taskId) {
8419        synchronized (this) {
8420            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8421                    "removeTask()");
8422            long ident = Binder.clearCallingIdentity();
8423            try {
8424                return removeTaskByIdLocked(taskId, true);
8425            } finally {
8426                Binder.restoreCallingIdentity(ident);
8427            }
8428        }
8429    }
8430
8431    /**
8432     * TODO: Add mController hook
8433     */
8434    @Override
8435    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8436        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8437                "moveTaskToFront()");
8438
8439        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8440        synchronized(this) {
8441            moveTaskToFrontLocked(taskId, flags, options);
8442        }
8443    }
8444
8445    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8446        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8447                Binder.getCallingUid(), -1, -1, "Task to front")) {
8448            ActivityOptions.abort(options);
8449            return;
8450        }
8451        final long origId = Binder.clearCallingIdentity();
8452        try {
8453            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8454            if (task == null) {
8455                Slog.d(TAG, "Could not find task for id: "+ taskId);
8456                return;
8457            }
8458            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8459                mStackSupervisor.showLockTaskToast();
8460                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8461                return;
8462            }
8463            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8464            if (prev != null && prev.isRecentsActivity()) {
8465                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8466            }
8467            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8468        } finally {
8469            Binder.restoreCallingIdentity(origId);
8470        }
8471        ActivityOptions.abort(options);
8472    }
8473
8474    @Override
8475    public void moveTaskToBack(int taskId) {
8476        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8477                "moveTaskToBack()");
8478
8479        synchronized(this) {
8480            TaskRecord tr = taskForIdLocked(taskId);
8481            if (tr != null) {
8482                if (tr == mStackSupervisor.mLockTaskModeTask) {
8483                    mStackSupervisor.showLockTaskToast();
8484                    return;
8485                }
8486                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8487                ActivityStack stack = tr.stack;
8488                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8489                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8490                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8491                        return;
8492                    }
8493                }
8494                final long origId = Binder.clearCallingIdentity();
8495                try {
8496                    stack.moveTaskToBackLocked(taskId, null);
8497                } finally {
8498                    Binder.restoreCallingIdentity(origId);
8499                }
8500            }
8501        }
8502    }
8503
8504    /**
8505     * Moves an activity, and all of the other activities within the same task, to the bottom
8506     * of the history stack.  The activity's order within the task is unchanged.
8507     *
8508     * @param token A reference to the activity we wish to move
8509     * @param nonRoot If false then this only works if the activity is the root
8510     *                of a task; if true it will work for any activity in a task.
8511     * @return Returns true if the move completed, false if not.
8512     */
8513    @Override
8514    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8515        enforceNotIsolatedCaller("moveActivityTaskToBack");
8516        synchronized(this) {
8517            final long origId = Binder.clearCallingIdentity();
8518            try {
8519                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8520                if (taskId >= 0) {
8521                    if ((mStackSupervisor.mLockTaskModeTask != null)
8522                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8523                        mStackSupervisor.showLockTaskToast();
8524                        return false;
8525                    }
8526                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8527                }
8528            } finally {
8529                Binder.restoreCallingIdentity(origId);
8530            }
8531        }
8532        return false;
8533    }
8534
8535    @Override
8536    public void moveTaskBackwards(int task) {
8537        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8538                "moveTaskBackwards()");
8539
8540        synchronized(this) {
8541            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8542                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8543                return;
8544            }
8545            final long origId = Binder.clearCallingIdentity();
8546            moveTaskBackwardsLocked(task);
8547            Binder.restoreCallingIdentity(origId);
8548        }
8549    }
8550
8551    private final void moveTaskBackwardsLocked(int task) {
8552        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8553    }
8554
8555    @Override
8556    public IBinder getHomeActivityToken() throws RemoteException {
8557        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8558                "getHomeActivityToken()");
8559        synchronized (this) {
8560            return mStackSupervisor.getHomeActivityToken();
8561        }
8562    }
8563
8564    @Override
8565    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8566            IActivityContainerCallback callback) throws RemoteException {
8567        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8568                "createActivityContainer()");
8569        synchronized (this) {
8570            if (parentActivityToken == null) {
8571                throw new IllegalArgumentException("parent token must not be null");
8572            }
8573            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8574            if (r == null) {
8575                return null;
8576            }
8577            if (callback == null) {
8578                throw new IllegalArgumentException("callback must not be null");
8579            }
8580            return mStackSupervisor.createActivityContainer(r, callback);
8581        }
8582    }
8583
8584    @Override
8585    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8586        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8587                "deleteActivityContainer()");
8588        synchronized (this) {
8589            mStackSupervisor.deleteActivityContainer(container);
8590        }
8591    }
8592
8593    @Override
8594    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8595            throws RemoteException {
8596        synchronized (this) {
8597            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8598            if (stack != null) {
8599                return stack.mActivityContainer;
8600            }
8601            return null;
8602        }
8603    }
8604
8605    @Override
8606    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8607        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8608                "moveTaskToStack()");
8609        if (stackId == HOME_STACK_ID) {
8610            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8611                    new RuntimeException("here").fillInStackTrace());
8612        }
8613        synchronized (this) {
8614            long ident = Binder.clearCallingIdentity();
8615            try {
8616                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8617                        + stackId + " toTop=" + toTop);
8618                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8619            } finally {
8620                Binder.restoreCallingIdentity(ident);
8621            }
8622        }
8623    }
8624
8625    @Override
8626    public void resizeStack(int stackBoxId, Rect bounds) {
8627        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8628                "resizeStackBox()");
8629        long ident = Binder.clearCallingIdentity();
8630        try {
8631            mWindowManager.resizeStack(stackBoxId, bounds);
8632        } finally {
8633            Binder.restoreCallingIdentity(ident);
8634        }
8635    }
8636
8637    @Override
8638    public List<StackInfo> getAllStackInfos() {
8639        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8640                "getAllStackInfos()");
8641        long ident = Binder.clearCallingIdentity();
8642        try {
8643            synchronized (this) {
8644                return mStackSupervisor.getAllStackInfosLocked();
8645            }
8646        } finally {
8647            Binder.restoreCallingIdentity(ident);
8648        }
8649    }
8650
8651    @Override
8652    public StackInfo getStackInfo(int stackId) {
8653        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8654                "getStackInfo()");
8655        long ident = Binder.clearCallingIdentity();
8656        try {
8657            synchronized (this) {
8658                return mStackSupervisor.getStackInfoLocked(stackId);
8659            }
8660        } finally {
8661            Binder.restoreCallingIdentity(ident);
8662        }
8663    }
8664
8665    @Override
8666    public boolean isInHomeStack(int taskId) {
8667        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8668                "getStackInfo()");
8669        long ident = Binder.clearCallingIdentity();
8670        try {
8671            synchronized (this) {
8672                TaskRecord tr = taskForIdLocked(taskId);
8673                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8674            }
8675        } finally {
8676            Binder.restoreCallingIdentity(ident);
8677        }
8678    }
8679
8680    @Override
8681    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8682        synchronized(this) {
8683            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8684        }
8685    }
8686
8687    private boolean isLockTaskAuthorized(String pkg) {
8688        final DevicePolicyManager dpm = (DevicePolicyManager)
8689                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8690        try {
8691            int uid = mContext.getPackageManager().getPackageUid(pkg,
8692                    Binder.getCallingUserHandle().getIdentifier());
8693            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8694        } catch (NameNotFoundException e) {
8695            return false;
8696        }
8697    }
8698
8699    void startLockTaskMode(TaskRecord task) {
8700        final String pkg;
8701        synchronized (this) {
8702            pkg = task.intent.getComponent().getPackageName();
8703        }
8704        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8705        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8706            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8707                    StatusBarManagerInternal.class);
8708            if (statusBarManager != null) {
8709                statusBarManager.showScreenPinningRequest();
8710            }
8711            return;
8712        }
8713        long ident = Binder.clearCallingIdentity();
8714        try {
8715            synchronized (this) {
8716                // Since we lost lock on task, make sure it is still there.
8717                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8718                if (task != null) {
8719                    if (!isSystemInitiated
8720                            && ((mStackSupervisor.getFocusedStack() == null)
8721                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8722                        throw new IllegalArgumentException("Invalid task, not in foreground");
8723                    }
8724                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8725                }
8726            }
8727        } finally {
8728            Binder.restoreCallingIdentity(ident);
8729        }
8730    }
8731
8732    @Override
8733    public void startLockTaskMode(int taskId) {
8734        final TaskRecord task;
8735        long ident = Binder.clearCallingIdentity();
8736        try {
8737            synchronized (this) {
8738                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8739            }
8740        } finally {
8741            Binder.restoreCallingIdentity(ident);
8742        }
8743        if (task != null) {
8744            startLockTaskMode(task);
8745        }
8746    }
8747
8748    @Override
8749    public void startLockTaskMode(IBinder token) {
8750        final TaskRecord task;
8751        long ident = Binder.clearCallingIdentity();
8752        try {
8753            synchronized (this) {
8754                final ActivityRecord r = ActivityRecord.forToken(token);
8755                if (r == null) {
8756                    return;
8757                }
8758                task = r.task;
8759            }
8760        } finally {
8761            Binder.restoreCallingIdentity(ident);
8762        }
8763        if (task != null) {
8764            startLockTaskMode(task);
8765        }
8766    }
8767
8768    @Override
8769    public void startLockTaskModeOnCurrent() throws RemoteException {
8770        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8771                "startLockTaskModeOnCurrent");
8772        long ident = Binder.clearCallingIdentity();
8773        try {
8774            ActivityRecord r = null;
8775            synchronized (this) {
8776                r = mStackSupervisor.topRunningActivityLocked();
8777            }
8778            startLockTaskMode(r.task);
8779        } finally {
8780            Binder.restoreCallingIdentity(ident);
8781        }
8782    }
8783
8784    @Override
8785    public void stopLockTaskMode() {
8786        // Verify that the user matches the package of the intent for the TaskRecord
8787        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8788        // and stopLockTaskMode.
8789        final int callingUid = Binder.getCallingUid();
8790        if (callingUid != Process.SYSTEM_UID) {
8791            try {
8792                String pkg =
8793                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8794                int uid = mContext.getPackageManager().getPackageUid(pkg,
8795                        Binder.getCallingUserHandle().getIdentifier());
8796                if (uid != callingUid) {
8797                    throw new SecurityException("Invalid uid, expected " + uid);
8798                }
8799            } catch (NameNotFoundException e) {
8800                Log.d(TAG, "stopLockTaskMode " + e);
8801                return;
8802            }
8803        }
8804        long ident = Binder.clearCallingIdentity();
8805        try {
8806            Log.d(TAG, "stopLockTaskMode");
8807            // Stop lock task
8808            synchronized (this) {
8809                mStackSupervisor.setLockTaskModeLocked(null, false);
8810            }
8811        } finally {
8812            Binder.restoreCallingIdentity(ident);
8813        }
8814    }
8815
8816    @Override
8817    public void stopLockTaskModeOnCurrent() throws RemoteException {
8818        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8819                "stopLockTaskModeOnCurrent");
8820        long ident = Binder.clearCallingIdentity();
8821        try {
8822            stopLockTaskMode();
8823        } finally {
8824            Binder.restoreCallingIdentity(ident);
8825        }
8826    }
8827
8828    @Override
8829    public boolean isInLockTaskMode() {
8830        synchronized (this) {
8831            return mStackSupervisor.isInLockTaskMode();
8832        }
8833    }
8834
8835    // =========================================================
8836    // CONTENT PROVIDERS
8837    // =========================================================
8838
8839    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8840        List<ProviderInfo> providers = null;
8841        try {
8842            providers = AppGlobals.getPackageManager().
8843                queryContentProviders(app.processName, app.uid,
8844                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8845        } catch (RemoteException ex) {
8846        }
8847        if (DEBUG_MU)
8848            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8849        int userId = app.userId;
8850        if (providers != null) {
8851            int N = providers.size();
8852            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8853            for (int i=0; i<N; i++) {
8854                ProviderInfo cpi =
8855                    (ProviderInfo)providers.get(i);
8856                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8857                        cpi.name, cpi.flags);
8858                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8859                    // This is a singleton provider, but a user besides the
8860                    // default user is asking to initialize a process it runs
8861                    // in...  well, no, it doesn't actually run in this process,
8862                    // it runs in the process of the default user.  Get rid of it.
8863                    providers.remove(i);
8864                    N--;
8865                    i--;
8866                    continue;
8867                }
8868
8869                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8870                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8871                if (cpr == null) {
8872                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8873                    mProviderMap.putProviderByClass(comp, cpr);
8874                }
8875                if (DEBUG_MU)
8876                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8877                app.pubProviders.put(cpi.name, cpr);
8878                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8879                    // Don't add this if it is a platform component that is marked
8880                    // to run in multiple processes, because this is actually
8881                    // part of the framework so doesn't make sense to track as a
8882                    // separate apk in the process.
8883                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8884                            mProcessStats);
8885                }
8886                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8887            }
8888        }
8889        return providers;
8890    }
8891
8892    /**
8893     * Check if {@link ProcessRecord} has a possible chance at accessing the
8894     * given {@link ProviderInfo}. Final permission checking is always done
8895     * in {@link ContentProvider}.
8896     */
8897    private final String checkContentProviderPermissionLocked(
8898            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8899        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8900        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8901        boolean checkedGrants = false;
8902        if (checkUser) {
8903            // Looking for cross-user grants before enforcing the typical cross-users permissions
8904            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8905            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8906                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8907                    return null;
8908                }
8909                checkedGrants = true;
8910            }
8911            userId = handleIncomingUser(callingPid, callingUid, userId,
8912                    false, ALLOW_NON_FULL,
8913                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8914            if (userId != tmpTargetUserId) {
8915                // When we actually went to determine the final targer user ID, this ended
8916                // up different than our initial check for the authority.  This is because
8917                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8918                // SELF.  So we need to re-check the grants again.
8919                checkedGrants = false;
8920            }
8921        }
8922        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8923                cpi.applicationInfo.uid, cpi.exported)
8924                == PackageManager.PERMISSION_GRANTED) {
8925            return null;
8926        }
8927        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8928                cpi.applicationInfo.uid, cpi.exported)
8929                == PackageManager.PERMISSION_GRANTED) {
8930            return null;
8931        }
8932
8933        PathPermission[] pps = cpi.pathPermissions;
8934        if (pps != null) {
8935            int i = pps.length;
8936            while (i > 0) {
8937                i--;
8938                PathPermission pp = pps[i];
8939                String pprperm = pp.getReadPermission();
8940                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8941                        cpi.applicationInfo.uid, cpi.exported)
8942                        == PackageManager.PERMISSION_GRANTED) {
8943                    return null;
8944                }
8945                String ppwperm = pp.getWritePermission();
8946                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8947                        cpi.applicationInfo.uid, cpi.exported)
8948                        == PackageManager.PERMISSION_GRANTED) {
8949                    return null;
8950                }
8951            }
8952        }
8953        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8954            return null;
8955        }
8956
8957        String msg;
8958        if (!cpi.exported) {
8959            msg = "Permission Denial: opening provider " + cpi.name
8960                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8961                    + ", uid=" + callingUid + ") that is not exported from uid "
8962                    + cpi.applicationInfo.uid;
8963        } else {
8964            msg = "Permission Denial: opening provider " + cpi.name
8965                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8966                    + ", uid=" + callingUid + ") requires "
8967                    + cpi.readPermission + " or " + cpi.writePermission;
8968        }
8969        Slog.w(TAG, msg);
8970        return msg;
8971    }
8972
8973    /**
8974     * Returns if the ContentProvider has granted a uri to callingUid
8975     */
8976    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8977        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8978        if (perms != null) {
8979            for (int i=perms.size()-1; i>=0; i--) {
8980                GrantUri grantUri = perms.keyAt(i);
8981                if (grantUri.sourceUserId == userId || !checkUser) {
8982                    if (matchesProvider(grantUri.uri, cpi)) {
8983                        return true;
8984                    }
8985                }
8986            }
8987        }
8988        return false;
8989    }
8990
8991    /**
8992     * Returns true if the uri authority is one of the authorities specified in the provider.
8993     */
8994    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8995        String uriAuth = uri.getAuthority();
8996        String cpiAuth = cpi.authority;
8997        if (cpiAuth.indexOf(';') == -1) {
8998            return cpiAuth.equals(uriAuth);
8999        }
9000        String[] cpiAuths = cpiAuth.split(";");
9001        int length = cpiAuths.length;
9002        for (int i = 0; i < length; i++) {
9003            if (cpiAuths[i].equals(uriAuth)) return true;
9004        }
9005        return false;
9006    }
9007
9008    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9009            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9010        if (r != null) {
9011            for (int i=0; i<r.conProviders.size(); i++) {
9012                ContentProviderConnection conn = r.conProviders.get(i);
9013                if (conn.provider == cpr) {
9014                    if (DEBUG_PROVIDER) Slog.v(TAG,
9015                            "Adding provider requested by "
9016                            + r.processName + " from process "
9017                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9018                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9019                    if (stable) {
9020                        conn.stableCount++;
9021                        conn.numStableIncs++;
9022                    } else {
9023                        conn.unstableCount++;
9024                        conn.numUnstableIncs++;
9025                    }
9026                    return conn;
9027                }
9028            }
9029            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9030            if (stable) {
9031                conn.stableCount = 1;
9032                conn.numStableIncs = 1;
9033            } else {
9034                conn.unstableCount = 1;
9035                conn.numUnstableIncs = 1;
9036            }
9037            cpr.connections.add(conn);
9038            r.conProviders.add(conn);
9039            return conn;
9040        }
9041        cpr.addExternalProcessHandleLocked(externalProcessToken);
9042        return null;
9043    }
9044
9045    boolean decProviderCountLocked(ContentProviderConnection conn,
9046            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9047        if (conn != null) {
9048            cpr = conn.provider;
9049            if (DEBUG_PROVIDER) Slog.v(TAG,
9050                    "Removing provider requested by "
9051                    + conn.client.processName + " from process "
9052                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9053                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9054            if (stable) {
9055                conn.stableCount--;
9056            } else {
9057                conn.unstableCount--;
9058            }
9059            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9060                cpr.connections.remove(conn);
9061                conn.client.conProviders.remove(conn);
9062                return true;
9063            }
9064            return false;
9065        }
9066        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9067        return false;
9068    }
9069
9070    private void checkTime(long startTime, String where) {
9071        long now = SystemClock.elapsedRealtime();
9072        if ((now-startTime) > 1000) {
9073            // If we are taking more than a second, log about it.
9074            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9075        }
9076    }
9077
9078    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9079            String name, IBinder token, boolean stable, int userId) {
9080        ContentProviderRecord cpr;
9081        ContentProviderConnection conn = null;
9082        ProviderInfo cpi = null;
9083
9084        synchronized(this) {
9085            long startTime = SystemClock.elapsedRealtime();
9086
9087            ProcessRecord r = null;
9088            if (caller != null) {
9089                r = getRecordForAppLocked(caller);
9090                if (r == null) {
9091                    throw new SecurityException(
9092                            "Unable to find app for caller " + caller
9093                          + " (pid=" + Binder.getCallingPid()
9094                          + ") when getting content provider " + name);
9095                }
9096            }
9097
9098            boolean checkCrossUser = true;
9099
9100            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9101
9102            // First check if this content provider has been published...
9103            cpr = mProviderMap.getProviderByName(name, userId);
9104            // If that didn't work, check if it exists for user 0 and then
9105            // verify that it's a singleton provider before using it.
9106            if (cpr == null && userId != UserHandle.USER_OWNER) {
9107                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9108                if (cpr != null) {
9109                    cpi = cpr.info;
9110                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9111                            cpi.name, cpi.flags)
9112                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9113                        userId = UserHandle.USER_OWNER;
9114                        checkCrossUser = false;
9115                    } else {
9116                        cpr = null;
9117                        cpi = null;
9118                    }
9119                }
9120            }
9121
9122            boolean providerRunning = cpr != null;
9123            if (providerRunning) {
9124                cpi = cpr.info;
9125                String msg;
9126                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9127                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9128                        != null) {
9129                    throw new SecurityException(msg);
9130                }
9131                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9132
9133                if (r != null && cpr.canRunHere(r)) {
9134                    // This provider has been published or is in the process
9135                    // of being published...  but it is also allowed to run
9136                    // in the caller's process, so don't make a connection
9137                    // and just let the caller instantiate its own instance.
9138                    ContentProviderHolder holder = cpr.newHolder(null);
9139                    // don't give caller the provider object, it needs
9140                    // to make its own.
9141                    holder.provider = null;
9142                    return holder;
9143                }
9144
9145                final long origId = Binder.clearCallingIdentity();
9146
9147                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9148
9149                // In this case the provider instance already exists, so we can
9150                // return it right away.
9151                conn = incProviderCountLocked(r, cpr, token, stable);
9152                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9153                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9154                        // If this is a perceptible app accessing the provider,
9155                        // make sure to count it as being accessed and thus
9156                        // back up on the LRU list.  This is good because
9157                        // content providers are often expensive to start.
9158                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9159                        updateLruProcessLocked(cpr.proc, false, null);
9160                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9161                    }
9162                }
9163
9164                if (cpr.proc != null) {
9165                    if (false) {
9166                        if (cpr.name.flattenToShortString().equals(
9167                                "com.android.providers.calendar/.CalendarProvider2")) {
9168                            Slog.v(TAG, "****************** KILLING "
9169                                + cpr.name.flattenToShortString());
9170                            Process.killProcess(cpr.proc.pid);
9171                        }
9172                    }
9173                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9174                    boolean success = updateOomAdjLocked(cpr.proc);
9175                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9176                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9177                    // NOTE: there is still a race here where a signal could be
9178                    // pending on the process even though we managed to update its
9179                    // adj level.  Not sure what to do about this, but at least
9180                    // the race is now smaller.
9181                    if (!success) {
9182                        // Uh oh...  it looks like the provider's process
9183                        // has been killed on us.  We need to wait for a new
9184                        // process to be started, and make sure its death
9185                        // doesn't kill our process.
9186                        Slog.i(TAG,
9187                                "Existing provider " + cpr.name.flattenToShortString()
9188                                + " is crashing; detaching " + r);
9189                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9190                        checkTime(startTime, "getContentProviderImpl: before appDied");
9191                        appDiedLocked(cpr.proc);
9192                        checkTime(startTime, "getContentProviderImpl: after appDied");
9193                        if (!lastRef) {
9194                            // This wasn't the last ref our process had on
9195                            // the provider...  we have now been killed, bail.
9196                            return null;
9197                        }
9198                        providerRunning = false;
9199                        conn = null;
9200                    }
9201                }
9202
9203                Binder.restoreCallingIdentity(origId);
9204            }
9205
9206            boolean singleton;
9207            if (!providerRunning) {
9208                try {
9209                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9210                    cpi = AppGlobals.getPackageManager().
9211                        resolveContentProvider(name,
9212                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9213                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9214                } catch (RemoteException ex) {
9215                }
9216                if (cpi == null) {
9217                    return null;
9218                }
9219                // If the provider is a singleton AND
9220                // (it's a call within the same user || the provider is a
9221                // privileged app)
9222                // Then allow connecting to the singleton provider
9223                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9224                        cpi.name, cpi.flags)
9225                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9226                if (singleton) {
9227                    userId = UserHandle.USER_OWNER;
9228                }
9229                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9230                checkTime(startTime, "getContentProviderImpl: got app info for user");
9231
9232                String msg;
9233                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9234                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9235                        != null) {
9236                    throw new SecurityException(msg);
9237                }
9238                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9239
9240                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9241                        && !cpi.processName.equals("system")) {
9242                    // If this content provider does not run in the system
9243                    // process, and the system is not yet ready to run other
9244                    // processes, then fail fast instead of hanging.
9245                    throw new IllegalArgumentException(
9246                            "Attempt to launch content provider before system ready");
9247                }
9248
9249                // Make sure that the user who owns this provider is running.  If not,
9250                // we don't want to allow it to run.
9251                if (!isUserRunningLocked(userId, false)) {
9252                    Slog.w(TAG, "Unable to launch app "
9253                            + cpi.applicationInfo.packageName + "/"
9254                            + cpi.applicationInfo.uid + " for provider "
9255                            + name + ": user " + userId + " is stopped");
9256                    return null;
9257                }
9258
9259                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9260                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9261                cpr = mProviderMap.getProviderByClass(comp, userId);
9262                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9263                final boolean firstClass = cpr == null;
9264                if (firstClass) {
9265                    final long ident = Binder.clearCallingIdentity();
9266                    try {
9267                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9268                        ApplicationInfo ai =
9269                            AppGlobals.getPackageManager().
9270                                getApplicationInfo(
9271                                        cpi.applicationInfo.packageName,
9272                                        STOCK_PM_FLAGS, userId);
9273                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9274                        if (ai == null) {
9275                            Slog.w(TAG, "No package info for content provider "
9276                                    + cpi.name);
9277                            return null;
9278                        }
9279                        ai = getAppInfoForUser(ai, userId);
9280                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9281                    } catch (RemoteException ex) {
9282                        // pm is in same process, this will never happen.
9283                    } finally {
9284                        Binder.restoreCallingIdentity(ident);
9285                    }
9286                }
9287
9288                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9289
9290                if (r != null && cpr.canRunHere(r)) {
9291                    // If this is a multiprocess provider, then just return its
9292                    // info and allow the caller to instantiate it.  Only do
9293                    // this if the provider is the same user as the caller's
9294                    // process, or can run as root (so can be in any process).
9295                    return cpr.newHolder(null);
9296                }
9297
9298                if (DEBUG_PROVIDER) {
9299                    RuntimeException e = new RuntimeException("here");
9300                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9301                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9302                }
9303
9304                // This is single process, and our app is now connecting to it.
9305                // See if we are already in the process of launching this
9306                // provider.
9307                final int N = mLaunchingProviders.size();
9308                int i;
9309                for (i=0; i<N; i++) {
9310                    if (mLaunchingProviders.get(i) == cpr) {
9311                        break;
9312                    }
9313                }
9314
9315                // If the provider is not already being launched, then get it
9316                // started.
9317                if (i >= N) {
9318                    final long origId = Binder.clearCallingIdentity();
9319
9320                    try {
9321                        // Content provider is now in use, its package can't be stopped.
9322                        try {
9323                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9324                            AppGlobals.getPackageManager().setPackageStoppedState(
9325                                    cpr.appInfo.packageName, false, userId);
9326                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9327                        } catch (RemoteException e) {
9328                        } catch (IllegalArgumentException e) {
9329                            Slog.w(TAG, "Failed trying to unstop package "
9330                                    + cpr.appInfo.packageName + ": " + e);
9331                        }
9332
9333                        // Use existing process if already started
9334                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9335                        ProcessRecord proc = getProcessRecordLocked(
9336                                cpi.processName, cpr.appInfo.uid, false);
9337                        if (proc != null && proc.thread != null) {
9338                            if (DEBUG_PROVIDER) {
9339                                Slog.d(TAG, "Installing in existing process " + proc);
9340                            }
9341                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9342                            proc.pubProviders.put(cpi.name, cpr);
9343                            try {
9344                                proc.thread.scheduleInstallProvider(cpi);
9345                            } catch (RemoteException e) {
9346                            }
9347                        } else {
9348                            checkTime(startTime, "getContentProviderImpl: before start process");
9349                            proc = startProcessLocked(cpi.processName,
9350                                    cpr.appInfo, false, 0, "content provider",
9351                                    new ComponentName(cpi.applicationInfo.packageName,
9352                                            cpi.name), false, false, false);
9353                            checkTime(startTime, "getContentProviderImpl: after start process");
9354                            if (proc == null) {
9355                                Slog.w(TAG, "Unable to launch app "
9356                                        + cpi.applicationInfo.packageName + "/"
9357                                        + cpi.applicationInfo.uid + " for provider "
9358                                        + name + ": process is bad");
9359                                return null;
9360                            }
9361                        }
9362                        cpr.launchingApp = proc;
9363                        mLaunchingProviders.add(cpr);
9364                    } finally {
9365                        Binder.restoreCallingIdentity(origId);
9366                    }
9367                }
9368
9369                checkTime(startTime, "getContentProviderImpl: updating data structures");
9370
9371                // Make sure the provider is published (the same provider class
9372                // may be published under multiple names).
9373                if (firstClass) {
9374                    mProviderMap.putProviderByClass(comp, cpr);
9375                }
9376
9377                mProviderMap.putProviderByName(name, cpr);
9378                conn = incProviderCountLocked(r, cpr, token, stable);
9379                if (conn != null) {
9380                    conn.waiting = true;
9381                }
9382            }
9383            checkTime(startTime, "getContentProviderImpl: done!");
9384        }
9385
9386        // Wait for the provider to be published...
9387        synchronized (cpr) {
9388            while (cpr.provider == null) {
9389                if (cpr.launchingApp == null) {
9390                    Slog.w(TAG, "Unable to launch app "
9391                            + cpi.applicationInfo.packageName + "/"
9392                            + cpi.applicationInfo.uid + " for provider "
9393                            + name + ": launching app became null");
9394                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9395                            UserHandle.getUserId(cpi.applicationInfo.uid),
9396                            cpi.applicationInfo.packageName,
9397                            cpi.applicationInfo.uid, name);
9398                    return null;
9399                }
9400                try {
9401                    if (DEBUG_MU) {
9402                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9403                                + cpr.launchingApp);
9404                    }
9405                    if (conn != null) {
9406                        conn.waiting = true;
9407                    }
9408                    cpr.wait();
9409                } catch (InterruptedException ex) {
9410                } finally {
9411                    if (conn != null) {
9412                        conn.waiting = false;
9413                    }
9414                }
9415            }
9416        }
9417        return cpr != null ? cpr.newHolder(conn) : null;
9418    }
9419
9420    @Override
9421    public final ContentProviderHolder getContentProvider(
9422            IApplicationThread caller, String name, int userId, boolean stable) {
9423        enforceNotIsolatedCaller("getContentProvider");
9424        if (caller == null) {
9425            String msg = "null IApplicationThread when getting content provider "
9426                    + name;
9427            Slog.w(TAG, msg);
9428            throw new SecurityException(msg);
9429        }
9430        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9431        // with cross-user grant.
9432        return getContentProviderImpl(caller, name, null, stable, userId);
9433    }
9434
9435    public ContentProviderHolder getContentProviderExternal(
9436            String name, int userId, IBinder token) {
9437        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9438            "Do not have permission in call getContentProviderExternal()");
9439        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9440                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9441        return getContentProviderExternalUnchecked(name, token, userId);
9442    }
9443
9444    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9445            IBinder token, int userId) {
9446        return getContentProviderImpl(null, name, token, true, userId);
9447    }
9448
9449    /**
9450     * Drop a content provider from a ProcessRecord's bookkeeping
9451     */
9452    public void removeContentProvider(IBinder connection, boolean stable) {
9453        enforceNotIsolatedCaller("removeContentProvider");
9454        long ident = Binder.clearCallingIdentity();
9455        try {
9456            synchronized (this) {
9457                ContentProviderConnection conn;
9458                try {
9459                    conn = (ContentProviderConnection)connection;
9460                } catch (ClassCastException e) {
9461                    String msg ="removeContentProvider: " + connection
9462                            + " not a ContentProviderConnection";
9463                    Slog.w(TAG, msg);
9464                    throw new IllegalArgumentException(msg);
9465                }
9466                if (conn == null) {
9467                    throw new NullPointerException("connection is null");
9468                }
9469                if (decProviderCountLocked(conn, null, null, stable)) {
9470                    updateOomAdjLocked();
9471                }
9472            }
9473        } finally {
9474            Binder.restoreCallingIdentity(ident);
9475        }
9476    }
9477
9478    public void removeContentProviderExternal(String name, IBinder token) {
9479        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9480            "Do not have permission in call removeContentProviderExternal()");
9481        int userId = UserHandle.getCallingUserId();
9482        long ident = Binder.clearCallingIdentity();
9483        try {
9484            removeContentProviderExternalUnchecked(name, token, userId);
9485        } finally {
9486            Binder.restoreCallingIdentity(ident);
9487        }
9488    }
9489
9490    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9491        synchronized (this) {
9492            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9493            if(cpr == null) {
9494                //remove from mProvidersByClass
9495                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9496                return;
9497            }
9498
9499            //update content provider record entry info
9500            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9501            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9502            if (localCpr.hasExternalProcessHandles()) {
9503                if (localCpr.removeExternalProcessHandleLocked(token)) {
9504                    updateOomAdjLocked();
9505                } else {
9506                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9507                            + " with no external reference for token: "
9508                            + token + ".");
9509                }
9510            } else {
9511                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9512                        + " with no external references.");
9513            }
9514        }
9515    }
9516
9517    public final void publishContentProviders(IApplicationThread caller,
9518            List<ContentProviderHolder> providers) {
9519        if (providers == null) {
9520            return;
9521        }
9522
9523        enforceNotIsolatedCaller("publishContentProviders");
9524        synchronized (this) {
9525            final ProcessRecord r = getRecordForAppLocked(caller);
9526            if (DEBUG_MU)
9527                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9528            if (r == null) {
9529                throw new SecurityException(
9530                        "Unable to find app for caller " + caller
9531                      + " (pid=" + Binder.getCallingPid()
9532                      + ") when publishing content providers");
9533            }
9534
9535            final long origId = Binder.clearCallingIdentity();
9536
9537            final int N = providers.size();
9538            for (int i=0; i<N; i++) {
9539                ContentProviderHolder src = providers.get(i);
9540                if (src == null || src.info == null || src.provider == null) {
9541                    continue;
9542                }
9543                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9544                if (DEBUG_MU)
9545                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9546                if (dst != null) {
9547                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9548                    mProviderMap.putProviderByClass(comp, dst);
9549                    String names[] = dst.info.authority.split(";");
9550                    for (int j = 0; j < names.length; j++) {
9551                        mProviderMap.putProviderByName(names[j], dst);
9552                    }
9553
9554                    int NL = mLaunchingProviders.size();
9555                    int j;
9556                    for (j=0; j<NL; j++) {
9557                        if (mLaunchingProviders.get(j) == dst) {
9558                            mLaunchingProviders.remove(j);
9559                            j--;
9560                            NL--;
9561                        }
9562                    }
9563                    synchronized (dst) {
9564                        dst.provider = src.provider;
9565                        dst.proc = r;
9566                        dst.notifyAll();
9567                    }
9568                    updateOomAdjLocked(r);
9569                }
9570            }
9571
9572            Binder.restoreCallingIdentity(origId);
9573        }
9574    }
9575
9576    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9577        ContentProviderConnection conn;
9578        try {
9579            conn = (ContentProviderConnection)connection;
9580        } catch (ClassCastException e) {
9581            String msg ="refContentProvider: " + connection
9582                    + " not a ContentProviderConnection";
9583            Slog.w(TAG, msg);
9584            throw new IllegalArgumentException(msg);
9585        }
9586        if (conn == null) {
9587            throw new NullPointerException("connection is null");
9588        }
9589
9590        synchronized (this) {
9591            if (stable > 0) {
9592                conn.numStableIncs += stable;
9593            }
9594            stable = conn.stableCount + stable;
9595            if (stable < 0) {
9596                throw new IllegalStateException("stableCount < 0: " + stable);
9597            }
9598
9599            if (unstable > 0) {
9600                conn.numUnstableIncs += unstable;
9601            }
9602            unstable = conn.unstableCount + unstable;
9603            if (unstable < 0) {
9604                throw new IllegalStateException("unstableCount < 0: " + unstable);
9605            }
9606
9607            if ((stable+unstable) <= 0) {
9608                throw new IllegalStateException("ref counts can't go to zero here: stable="
9609                        + stable + " unstable=" + unstable);
9610            }
9611            conn.stableCount = stable;
9612            conn.unstableCount = unstable;
9613            return !conn.dead;
9614        }
9615    }
9616
9617    public void unstableProviderDied(IBinder connection) {
9618        ContentProviderConnection conn;
9619        try {
9620            conn = (ContentProviderConnection)connection;
9621        } catch (ClassCastException e) {
9622            String msg ="refContentProvider: " + connection
9623                    + " not a ContentProviderConnection";
9624            Slog.w(TAG, msg);
9625            throw new IllegalArgumentException(msg);
9626        }
9627        if (conn == null) {
9628            throw new NullPointerException("connection is null");
9629        }
9630
9631        // Safely retrieve the content provider associated with the connection.
9632        IContentProvider provider;
9633        synchronized (this) {
9634            provider = conn.provider.provider;
9635        }
9636
9637        if (provider == null) {
9638            // Um, yeah, we're way ahead of you.
9639            return;
9640        }
9641
9642        // Make sure the caller is being honest with us.
9643        if (provider.asBinder().pingBinder()) {
9644            // Er, no, still looks good to us.
9645            synchronized (this) {
9646                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9647                        + " says " + conn + " died, but we don't agree");
9648                return;
9649            }
9650        }
9651
9652        // Well look at that!  It's dead!
9653        synchronized (this) {
9654            if (conn.provider.provider != provider) {
9655                // But something changed...  good enough.
9656                return;
9657            }
9658
9659            ProcessRecord proc = conn.provider.proc;
9660            if (proc == null || proc.thread == null) {
9661                // Seems like the process is already cleaned up.
9662                return;
9663            }
9664
9665            // As far as we're concerned, this is just like receiving a
9666            // death notification...  just a bit prematurely.
9667            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9668                    + ") early provider death");
9669            final long ident = Binder.clearCallingIdentity();
9670            try {
9671                appDiedLocked(proc);
9672            } finally {
9673                Binder.restoreCallingIdentity(ident);
9674            }
9675        }
9676    }
9677
9678    @Override
9679    public void appNotRespondingViaProvider(IBinder connection) {
9680        enforceCallingPermission(
9681                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9682
9683        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9684        if (conn == null) {
9685            Slog.w(TAG, "ContentProviderConnection is null");
9686            return;
9687        }
9688
9689        final ProcessRecord host = conn.provider.proc;
9690        if (host == null) {
9691            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9692            return;
9693        }
9694
9695        final long token = Binder.clearCallingIdentity();
9696        try {
9697            appNotResponding(host, null, null, false, "ContentProvider not responding");
9698        } finally {
9699            Binder.restoreCallingIdentity(token);
9700        }
9701    }
9702
9703    public final void installSystemProviders() {
9704        List<ProviderInfo> providers;
9705        synchronized (this) {
9706            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9707            providers = generateApplicationProvidersLocked(app);
9708            if (providers != null) {
9709                for (int i=providers.size()-1; i>=0; i--) {
9710                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9711                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9712                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9713                                + ": not system .apk");
9714                        providers.remove(i);
9715                    }
9716                }
9717            }
9718        }
9719        if (providers != null) {
9720            mSystemThread.installSystemProviders(providers);
9721        }
9722
9723        mCoreSettingsObserver = new CoreSettingsObserver(this);
9724
9725        //mUsageStatsService.monitorPackages();
9726    }
9727
9728    /**
9729     * Allows apps to retrieve the MIME type of a URI.
9730     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9731     * users, then it does not need permission to access the ContentProvider.
9732     * Either, it needs cross-user uri grants.
9733     *
9734     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9735     *
9736     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9737     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9738     */
9739    public String getProviderMimeType(Uri uri, int userId) {
9740        enforceNotIsolatedCaller("getProviderMimeType");
9741        final String name = uri.getAuthority();
9742        int callingUid = Binder.getCallingUid();
9743        int callingPid = Binder.getCallingPid();
9744        long ident = 0;
9745        boolean clearedIdentity = false;
9746        userId = unsafeConvertIncomingUser(userId);
9747        if (canClearIdentity(callingPid, callingUid, userId)) {
9748            clearedIdentity = true;
9749            ident = Binder.clearCallingIdentity();
9750        }
9751        ContentProviderHolder holder = null;
9752        try {
9753            holder = getContentProviderExternalUnchecked(name, null, userId);
9754            if (holder != null) {
9755                return holder.provider.getType(uri);
9756            }
9757        } catch (RemoteException e) {
9758            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9759            return null;
9760        } finally {
9761            // We need to clear the identity to call removeContentProviderExternalUnchecked
9762            if (!clearedIdentity) {
9763                ident = Binder.clearCallingIdentity();
9764            }
9765            try {
9766                if (holder != null) {
9767                    removeContentProviderExternalUnchecked(name, null, userId);
9768                }
9769            } finally {
9770                Binder.restoreCallingIdentity(ident);
9771            }
9772        }
9773
9774        return null;
9775    }
9776
9777    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9778        if (UserHandle.getUserId(callingUid) == userId) {
9779            return true;
9780        }
9781        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9782                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9783                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9784                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9785                return true;
9786        }
9787        return false;
9788    }
9789
9790    // =========================================================
9791    // GLOBAL MANAGEMENT
9792    // =========================================================
9793
9794    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9795            boolean isolated, int isolatedUid) {
9796        String proc = customProcess != null ? customProcess : info.processName;
9797        BatteryStatsImpl.Uid.Proc ps = null;
9798        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9799        int uid = info.uid;
9800        if (isolated) {
9801            if (isolatedUid == 0) {
9802                int userId = UserHandle.getUserId(uid);
9803                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9804                while (true) {
9805                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9806                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9807                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9808                    }
9809                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9810                    mNextIsolatedProcessUid++;
9811                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9812                        // No process for this uid, use it.
9813                        break;
9814                    }
9815                    stepsLeft--;
9816                    if (stepsLeft <= 0) {
9817                        return null;
9818                    }
9819                }
9820            } else {
9821                // Special case for startIsolatedProcess (internal only), where
9822                // the uid of the isolated process is specified by the caller.
9823                uid = isolatedUid;
9824            }
9825        }
9826        return new ProcessRecord(stats, info, proc, uid);
9827    }
9828
9829    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9830            String abiOverride) {
9831        ProcessRecord app;
9832        if (!isolated) {
9833            app = getProcessRecordLocked(info.processName, info.uid, true);
9834        } else {
9835            app = null;
9836        }
9837
9838        if (app == null) {
9839            app = newProcessRecordLocked(info, null, isolated, 0);
9840            mProcessNames.put(info.processName, app.uid, app);
9841            if (isolated) {
9842                mIsolatedProcesses.put(app.uid, app);
9843            }
9844            updateLruProcessLocked(app, false, null);
9845            updateOomAdjLocked();
9846        }
9847
9848        // This package really, really can not be stopped.
9849        try {
9850            AppGlobals.getPackageManager().setPackageStoppedState(
9851                    info.packageName, false, UserHandle.getUserId(app.uid));
9852        } catch (RemoteException e) {
9853        } catch (IllegalArgumentException e) {
9854            Slog.w(TAG, "Failed trying to unstop package "
9855                    + info.packageName + ": " + e);
9856        }
9857
9858        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9859                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9860            app.persistent = true;
9861            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9862        }
9863        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9864            mPersistentStartingProcesses.add(app);
9865            startProcessLocked(app, "added application", app.processName, abiOverride,
9866                    null /* entryPoint */, null /* entryPointArgs */);
9867        }
9868
9869        return app;
9870    }
9871
9872    public void unhandledBack() {
9873        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9874                "unhandledBack()");
9875
9876        synchronized(this) {
9877            final long origId = Binder.clearCallingIdentity();
9878            try {
9879                getFocusedStack().unhandledBackLocked();
9880            } finally {
9881                Binder.restoreCallingIdentity(origId);
9882            }
9883        }
9884    }
9885
9886    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9887        enforceNotIsolatedCaller("openContentUri");
9888        final int userId = UserHandle.getCallingUserId();
9889        String name = uri.getAuthority();
9890        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9891        ParcelFileDescriptor pfd = null;
9892        if (cph != null) {
9893            // We record the binder invoker's uid in thread-local storage before
9894            // going to the content provider to open the file.  Later, in the code
9895            // that handles all permissions checks, we look for this uid and use
9896            // that rather than the Activity Manager's own uid.  The effect is that
9897            // we do the check against the caller's permissions even though it looks
9898            // to the content provider like the Activity Manager itself is making
9899            // the request.
9900            Binder token = new Binder();
9901            sCallerIdentity.set(new Identity(
9902                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9903            try {
9904                pfd = cph.provider.openFile(null, uri, "r", null, token);
9905            } catch (FileNotFoundException e) {
9906                // do nothing; pfd will be returned null
9907            } finally {
9908                // Ensure that whatever happens, we clean up the identity state
9909                sCallerIdentity.remove();
9910            }
9911
9912            // We've got the fd now, so we're done with the provider.
9913            removeContentProviderExternalUnchecked(name, null, userId);
9914        } else {
9915            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9916        }
9917        return pfd;
9918    }
9919
9920    // Actually is sleeping or shutting down or whatever else in the future
9921    // is an inactive state.
9922    public boolean isSleepingOrShuttingDown() {
9923        return isSleeping() || mShuttingDown;
9924    }
9925
9926    public boolean isSleeping() {
9927        return mSleeping;
9928    }
9929
9930    void onWakefulnessChanged(int wakefulness) {
9931        synchronized(this) {
9932            mWakefulness = wakefulness;
9933            updateSleepIfNeededLocked();
9934        }
9935    }
9936
9937    void finishRunningVoiceLocked() {
9938        if (mRunningVoice) {
9939            mRunningVoice = false;
9940            updateSleepIfNeededLocked();
9941        }
9942    }
9943
9944    void updateSleepIfNeededLocked() {
9945        if (mSleeping && !shouldSleepLocked()) {
9946            mSleeping = false;
9947            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9948        } else if (!mSleeping && shouldSleepLocked()) {
9949            mSleeping = true;
9950            mStackSupervisor.goingToSleepLocked();
9951
9952            // Initialize the wake times of all processes.
9953            checkExcessivePowerUsageLocked(false);
9954            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9955            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9956            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9957        }
9958    }
9959
9960    private boolean shouldSleepLocked() {
9961        // Resume applications while running a voice interactor.
9962        if (mRunningVoice) {
9963            return false;
9964        }
9965
9966        switch (mWakefulness) {
9967            case PowerManagerInternal.WAKEFULNESS_AWAKE:
9968            case PowerManagerInternal.WAKEFULNESS_DREAMING:
9969                // If we're interactive but applications are already paused then defer
9970                // resuming them until the lock screen is hidden.
9971                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
9972            case PowerManagerInternal.WAKEFULNESS_DOZING:
9973                // If we're dozing then pause applications whenever the lock screen is shown.
9974                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
9975            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
9976            default:
9977                // If we're asleep then pause applications unconditionally.
9978                return true;
9979        }
9980    }
9981
9982    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9983        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9984            // Never persist the home stack.
9985            return;
9986        }
9987        mTaskPersister.wakeup(task, flush);
9988    }
9989
9990    @Override
9991    public boolean shutdown(int timeout) {
9992        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9993                != PackageManager.PERMISSION_GRANTED) {
9994            throw new SecurityException("Requires permission "
9995                    + android.Manifest.permission.SHUTDOWN);
9996        }
9997
9998        boolean timedout = false;
9999
10000        synchronized(this) {
10001            mShuttingDown = true;
10002            updateEventDispatchingLocked();
10003            timedout = mStackSupervisor.shutdownLocked(timeout);
10004        }
10005
10006        mAppOpsService.shutdown();
10007        if (mUsageStatsService != null) {
10008            mUsageStatsService.prepareShutdown();
10009        }
10010        mBatteryStatsService.shutdown();
10011        synchronized (this) {
10012            mProcessStats.shutdownLocked();
10013        }
10014        notifyTaskPersisterLocked(null, true);
10015
10016        return timedout;
10017    }
10018
10019    public final void activitySlept(IBinder token) {
10020        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10021
10022        final long origId = Binder.clearCallingIdentity();
10023
10024        synchronized (this) {
10025            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10026            if (r != null) {
10027                mStackSupervisor.activitySleptLocked(r);
10028            }
10029        }
10030
10031        Binder.restoreCallingIdentity(origId);
10032    }
10033
10034    private String lockScreenShownToString() {
10035        switch (mLockScreenShown) {
10036            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10037            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10038            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10039            default: return "Unknown=" + mLockScreenShown;
10040        }
10041    }
10042
10043    void logLockScreen(String msg) {
10044        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10045                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10046                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10047                + " mSleeping=" + mSleeping);
10048    }
10049
10050    void startRunningVoiceLocked() {
10051        if (!mRunningVoice) {
10052            mRunningVoice = true;
10053            updateSleepIfNeededLocked();
10054        }
10055    }
10056
10057    private void updateEventDispatchingLocked() {
10058        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10059    }
10060
10061    public void setLockScreenShown(boolean shown) {
10062        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10063                != PackageManager.PERMISSION_GRANTED) {
10064            throw new SecurityException("Requires permission "
10065                    + android.Manifest.permission.DEVICE_POWER);
10066        }
10067
10068        synchronized(this) {
10069            long ident = Binder.clearCallingIdentity();
10070            try {
10071                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10072                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10073                updateSleepIfNeededLocked();
10074            } finally {
10075                Binder.restoreCallingIdentity(ident);
10076            }
10077        }
10078    }
10079
10080    @Override
10081    public void stopAppSwitches() {
10082        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10083                != PackageManager.PERMISSION_GRANTED) {
10084            throw new SecurityException("Requires permission "
10085                    + android.Manifest.permission.STOP_APP_SWITCHES);
10086        }
10087
10088        synchronized(this) {
10089            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10090                    + APP_SWITCH_DELAY_TIME;
10091            mDidAppSwitch = false;
10092            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10093            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10094            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10095        }
10096    }
10097
10098    public void resumeAppSwitches() {
10099        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10100                != PackageManager.PERMISSION_GRANTED) {
10101            throw new SecurityException("Requires permission "
10102                    + android.Manifest.permission.STOP_APP_SWITCHES);
10103        }
10104
10105        synchronized(this) {
10106            // Note that we don't execute any pending app switches... we will
10107            // let those wait until either the timeout, or the next start
10108            // activity request.
10109            mAppSwitchesAllowedTime = 0;
10110        }
10111    }
10112
10113    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10114            int callingPid, int callingUid, String name) {
10115        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10116            return true;
10117        }
10118
10119        int perm = checkComponentPermission(
10120                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10121                sourceUid, -1, true);
10122        if (perm == PackageManager.PERMISSION_GRANTED) {
10123            return true;
10124        }
10125
10126        // If the actual IPC caller is different from the logical source, then
10127        // also see if they are allowed to control app switches.
10128        if (callingUid != -1 && callingUid != sourceUid) {
10129            perm = checkComponentPermission(
10130                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10131                    callingUid, -1, true);
10132            if (perm == PackageManager.PERMISSION_GRANTED) {
10133                return true;
10134            }
10135        }
10136
10137        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10138        return false;
10139    }
10140
10141    public void setDebugApp(String packageName, boolean waitForDebugger,
10142            boolean persistent) {
10143        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10144                "setDebugApp()");
10145
10146        long ident = Binder.clearCallingIdentity();
10147        try {
10148            // Note that this is not really thread safe if there are multiple
10149            // callers into it at the same time, but that's not a situation we
10150            // care about.
10151            if (persistent) {
10152                final ContentResolver resolver = mContext.getContentResolver();
10153                Settings.Global.putString(
10154                    resolver, Settings.Global.DEBUG_APP,
10155                    packageName);
10156                Settings.Global.putInt(
10157                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10158                    waitForDebugger ? 1 : 0);
10159            }
10160
10161            synchronized (this) {
10162                if (!persistent) {
10163                    mOrigDebugApp = mDebugApp;
10164                    mOrigWaitForDebugger = mWaitForDebugger;
10165                }
10166                mDebugApp = packageName;
10167                mWaitForDebugger = waitForDebugger;
10168                mDebugTransient = !persistent;
10169                if (packageName != null) {
10170                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10171                            false, UserHandle.USER_ALL, "set debug app");
10172                }
10173            }
10174        } finally {
10175            Binder.restoreCallingIdentity(ident);
10176        }
10177    }
10178
10179    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10180        synchronized (this) {
10181            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10182            if (!isDebuggable) {
10183                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10184                    throw new SecurityException("Process not debuggable: " + app.packageName);
10185                }
10186            }
10187
10188            mOpenGlTraceApp = processName;
10189        }
10190    }
10191
10192    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10193        synchronized (this) {
10194            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10195            if (!isDebuggable) {
10196                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10197                    throw new SecurityException("Process not debuggable: " + app.packageName);
10198                }
10199            }
10200            mProfileApp = processName;
10201            mProfileFile = profilerInfo.profileFile;
10202            if (mProfileFd != null) {
10203                try {
10204                    mProfileFd.close();
10205                } catch (IOException e) {
10206                }
10207                mProfileFd = null;
10208            }
10209            mProfileFd = profilerInfo.profileFd;
10210            mSamplingInterval = profilerInfo.samplingInterval;
10211            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10212            mProfileType = 0;
10213        }
10214    }
10215
10216    @Override
10217    public void setAlwaysFinish(boolean enabled) {
10218        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10219                "setAlwaysFinish()");
10220
10221        Settings.Global.putInt(
10222                mContext.getContentResolver(),
10223                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10224
10225        synchronized (this) {
10226            mAlwaysFinishActivities = enabled;
10227        }
10228    }
10229
10230    @Override
10231    public void setActivityController(IActivityController controller) {
10232        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10233                "setActivityController()");
10234        synchronized (this) {
10235            mController = controller;
10236            Watchdog.getInstance().setActivityController(controller);
10237        }
10238    }
10239
10240    @Override
10241    public void setUserIsMonkey(boolean userIsMonkey) {
10242        synchronized (this) {
10243            synchronized (mPidsSelfLocked) {
10244                final int callingPid = Binder.getCallingPid();
10245                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10246                if (precessRecord == null) {
10247                    throw new SecurityException("Unknown process: " + callingPid);
10248                }
10249                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10250                    throw new SecurityException("Only an instrumentation process "
10251                            + "with a UiAutomation can call setUserIsMonkey");
10252                }
10253            }
10254            mUserIsMonkey = userIsMonkey;
10255        }
10256    }
10257
10258    @Override
10259    public boolean isUserAMonkey() {
10260        synchronized (this) {
10261            // If there is a controller also implies the user is a monkey.
10262            return (mUserIsMonkey || mController != null);
10263        }
10264    }
10265
10266    public void requestBugReport() {
10267        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10268        SystemProperties.set("ctl.start", "bugreport");
10269    }
10270
10271    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10272        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10273    }
10274
10275    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10276        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10277            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10278        }
10279        return KEY_DISPATCHING_TIMEOUT;
10280    }
10281
10282    @Override
10283    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10284        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10285                != PackageManager.PERMISSION_GRANTED) {
10286            throw new SecurityException("Requires permission "
10287                    + android.Manifest.permission.FILTER_EVENTS);
10288        }
10289        ProcessRecord proc;
10290        long timeout;
10291        synchronized (this) {
10292            synchronized (mPidsSelfLocked) {
10293                proc = mPidsSelfLocked.get(pid);
10294            }
10295            timeout = getInputDispatchingTimeoutLocked(proc);
10296        }
10297
10298        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10299            return -1;
10300        }
10301
10302        return timeout;
10303    }
10304
10305    /**
10306     * Handle input dispatching timeouts.
10307     * Returns whether input dispatching should be aborted or not.
10308     */
10309    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10310            final ActivityRecord activity, final ActivityRecord parent,
10311            final boolean aboveSystem, String reason) {
10312        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10313                != PackageManager.PERMISSION_GRANTED) {
10314            throw new SecurityException("Requires permission "
10315                    + android.Manifest.permission.FILTER_EVENTS);
10316        }
10317
10318        final String annotation;
10319        if (reason == null) {
10320            annotation = "Input dispatching timed out";
10321        } else {
10322            annotation = "Input dispatching timed out (" + reason + ")";
10323        }
10324
10325        if (proc != null) {
10326            synchronized (this) {
10327                if (proc.debugging) {
10328                    return false;
10329                }
10330
10331                if (mDidDexOpt) {
10332                    // Give more time since we were dexopting.
10333                    mDidDexOpt = false;
10334                    return false;
10335                }
10336
10337                if (proc.instrumentationClass != null) {
10338                    Bundle info = new Bundle();
10339                    info.putString("shortMsg", "keyDispatchingTimedOut");
10340                    info.putString("longMsg", annotation);
10341                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10342                    return true;
10343                }
10344            }
10345            mHandler.post(new Runnable() {
10346                @Override
10347                public void run() {
10348                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10349                }
10350            });
10351        }
10352
10353        return true;
10354    }
10355
10356    public Bundle getAssistContextExtras(int requestType) {
10357        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10358                UserHandle.getCallingUserId());
10359        if (pae == null) {
10360            return null;
10361        }
10362        synchronized (pae) {
10363            while (!pae.haveResult) {
10364                try {
10365                    pae.wait();
10366                } catch (InterruptedException e) {
10367                }
10368            }
10369            if (pae.result != null) {
10370                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10371            }
10372        }
10373        synchronized (this) {
10374            mPendingAssistExtras.remove(pae);
10375            mHandler.removeCallbacks(pae);
10376        }
10377        return pae.extras;
10378    }
10379
10380    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10381            int userHandle) {
10382        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10383                "getAssistContextExtras()");
10384        PendingAssistExtras pae;
10385        Bundle extras = new Bundle();
10386        synchronized (this) {
10387            ActivityRecord activity = getFocusedStack().mResumedActivity;
10388            if (activity == null) {
10389                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10390                return null;
10391            }
10392            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10393            if (activity.app == null || activity.app.thread == null) {
10394                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10395                return null;
10396            }
10397            if (activity.app.pid == Binder.getCallingPid()) {
10398                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10399                return null;
10400            }
10401            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10402            try {
10403                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10404                        requestType);
10405                mPendingAssistExtras.add(pae);
10406                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10407            } catch (RemoteException e) {
10408                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10409                return null;
10410            }
10411            return pae;
10412        }
10413    }
10414
10415    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10416        PendingAssistExtras pae = (PendingAssistExtras)token;
10417        synchronized (pae) {
10418            pae.result = extras;
10419            pae.haveResult = true;
10420            pae.notifyAll();
10421            if (pae.intent == null) {
10422                // Caller is just waiting for the result.
10423                return;
10424            }
10425        }
10426
10427        // We are now ready to launch the assist activity.
10428        synchronized (this) {
10429            boolean exists = mPendingAssistExtras.remove(pae);
10430            mHandler.removeCallbacks(pae);
10431            if (!exists) {
10432                // Timed out.
10433                return;
10434            }
10435        }
10436        pae.intent.replaceExtras(extras);
10437        if (pae.hint != null) {
10438            pae.intent.putExtra(pae.hint, true);
10439        }
10440        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10441                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10442                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10443        closeSystemDialogs("assist");
10444        try {
10445            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10446        } catch (ActivityNotFoundException e) {
10447            Slog.w(TAG, "No activity to handle assist action.", e);
10448        }
10449    }
10450
10451    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10452        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10453    }
10454
10455    public void registerProcessObserver(IProcessObserver observer) {
10456        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10457                "registerProcessObserver()");
10458        synchronized (this) {
10459            mProcessObservers.register(observer);
10460        }
10461    }
10462
10463    @Override
10464    public void unregisterProcessObserver(IProcessObserver observer) {
10465        synchronized (this) {
10466            mProcessObservers.unregister(observer);
10467        }
10468    }
10469
10470    @Override
10471    public boolean convertFromTranslucent(IBinder token) {
10472        final long origId = Binder.clearCallingIdentity();
10473        try {
10474            synchronized (this) {
10475                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10476                if (r == null) {
10477                    return false;
10478                }
10479                final boolean translucentChanged = r.changeWindowTranslucency(true);
10480                if (translucentChanged) {
10481                    r.task.stack.releaseBackgroundResources();
10482                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10483                }
10484                mWindowManager.setAppFullscreen(token, true);
10485                return translucentChanged;
10486            }
10487        } finally {
10488            Binder.restoreCallingIdentity(origId);
10489        }
10490    }
10491
10492    @Override
10493    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10494        final long origId = Binder.clearCallingIdentity();
10495        try {
10496            synchronized (this) {
10497                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10498                if (r == null) {
10499                    return false;
10500                }
10501                int index = r.task.mActivities.lastIndexOf(r);
10502                if (index > 0) {
10503                    ActivityRecord under = r.task.mActivities.get(index - 1);
10504                    under.returningOptions = options;
10505                }
10506                final boolean translucentChanged = r.changeWindowTranslucency(false);
10507                if (translucentChanged) {
10508                    r.task.stack.convertToTranslucent(r);
10509                }
10510                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10511                mWindowManager.setAppFullscreen(token, false);
10512                return translucentChanged;
10513            }
10514        } finally {
10515            Binder.restoreCallingIdentity(origId);
10516        }
10517    }
10518
10519    @Override
10520    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10521        final long origId = Binder.clearCallingIdentity();
10522        try {
10523            synchronized (this) {
10524                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10525                if (r != null) {
10526                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10527                }
10528            }
10529            return false;
10530        } finally {
10531            Binder.restoreCallingIdentity(origId);
10532        }
10533    }
10534
10535    @Override
10536    public boolean isBackgroundVisibleBehind(IBinder token) {
10537        final long origId = Binder.clearCallingIdentity();
10538        try {
10539            synchronized (this) {
10540                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10541                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10542                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10543                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10544                return visible;
10545            }
10546        } finally {
10547            Binder.restoreCallingIdentity(origId);
10548        }
10549    }
10550
10551    @Override
10552    public ActivityOptions getActivityOptions(IBinder token) {
10553        final long origId = Binder.clearCallingIdentity();
10554        try {
10555            synchronized (this) {
10556                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10557                if (r != null) {
10558                    final ActivityOptions activityOptions = r.pendingOptions;
10559                    r.pendingOptions = null;
10560                    return activityOptions;
10561                }
10562                return null;
10563            }
10564        } finally {
10565            Binder.restoreCallingIdentity(origId);
10566        }
10567    }
10568
10569    @Override
10570    public void setImmersive(IBinder token, boolean immersive) {
10571        synchronized(this) {
10572            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10573            if (r == null) {
10574                throw new IllegalArgumentException();
10575            }
10576            r.immersive = immersive;
10577
10578            // update associated state if we're frontmost
10579            if (r == mFocusedActivity) {
10580                if (DEBUG_IMMERSIVE) {
10581                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10582                }
10583                applyUpdateLockStateLocked(r);
10584            }
10585        }
10586    }
10587
10588    @Override
10589    public boolean isImmersive(IBinder token) {
10590        synchronized (this) {
10591            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10592            if (r == null) {
10593                throw new IllegalArgumentException();
10594            }
10595            return r.immersive;
10596        }
10597    }
10598
10599    public boolean isTopActivityImmersive() {
10600        enforceNotIsolatedCaller("startActivity");
10601        synchronized (this) {
10602            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10603            return (r != null) ? r.immersive : false;
10604        }
10605    }
10606
10607    @Override
10608    public boolean isTopOfTask(IBinder token) {
10609        synchronized (this) {
10610            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10611            if (r == null) {
10612                throw new IllegalArgumentException();
10613            }
10614            return r.task.getTopActivity() == r;
10615        }
10616    }
10617
10618    public final void enterSafeMode() {
10619        synchronized(this) {
10620            // It only makes sense to do this before the system is ready
10621            // and started launching other packages.
10622            if (!mSystemReady) {
10623                try {
10624                    AppGlobals.getPackageManager().enterSafeMode();
10625                } catch (RemoteException e) {
10626                }
10627            }
10628
10629            mSafeMode = true;
10630        }
10631    }
10632
10633    public final void showSafeModeOverlay() {
10634        View v = LayoutInflater.from(mContext).inflate(
10635                com.android.internal.R.layout.safe_mode, null);
10636        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10637        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10638        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10639        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10640        lp.gravity = Gravity.BOTTOM | Gravity.START;
10641        lp.format = v.getBackground().getOpacity();
10642        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10643                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10644        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10645        ((WindowManager)mContext.getSystemService(
10646                Context.WINDOW_SERVICE)).addView(v, lp);
10647    }
10648
10649    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10650        if (!(sender instanceof PendingIntentRecord)) {
10651            return;
10652        }
10653        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10654        synchronized (stats) {
10655            if (mBatteryStatsService.isOnBattery()) {
10656                mBatteryStatsService.enforceCallingPermission();
10657                PendingIntentRecord rec = (PendingIntentRecord)sender;
10658                int MY_UID = Binder.getCallingUid();
10659                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10660                BatteryStatsImpl.Uid.Pkg pkg =
10661                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10662                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10663                pkg.incWakeupsLocked();
10664            }
10665        }
10666    }
10667
10668    public boolean killPids(int[] pids, String pReason, boolean secure) {
10669        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10670            throw new SecurityException("killPids only available to the system");
10671        }
10672        String reason = (pReason == null) ? "Unknown" : pReason;
10673        // XXX Note: don't acquire main activity lock here, because the window
10674        // manager calls in with its locks held.
10675
10676        boolean killed = false;
10677        synchronized (mPidsSelfLocked) {
10678            int[] types = new int[pids.length];
10679            int worstType = 0;
10680            for (int i=0; i<pids.length; i++) {
10681                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10682                if (proc != null) {
10683                    int type = proc.setAdj;
10684                    types[i] = type;
10685                    if (type > worstType) {
10686                        worstType = type;
10687                    }
10688                }
10689            }
10690
10691            // If the worst oom_adj is somewhere in the cached proc LRU range,
10692            // then constrain it so we will kill all cached procs.
10693            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10694                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10695                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10696            }
10697
10698            // If this is not a secure call, don't let it kill processes that
10699            // are important.
10700            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10701                worstType = ProcessList.SERVICE_ADJ;
10702            }
10703
10704            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10705            for (int i=0; i<pids.length; i++) {
10706                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10707                if (proc == null) {
10708                    continue;
10709                }
10710                int adj = proc.setAdj;
10711                if (adj >= worstType && !proc.killedByAm) {
10712                    proc.kill(reason, true);
10713                    killed = true;
10714                }
10715            }
10716        }
10717        return killed;
10718    }
10719
10720    @Override
10721    public void killUid(int uid, String reason) {
10722        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10723            throw new SecurityException("killUid only available to the system");
10724        }
10725        synchronized (this) {
10726            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10727                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10728                    reason != null ? reason : "kill uid");
10729        }
10730    }
10731
10732    @Override
10733    public boolean killProcessesBelowForeground(String reason) {
10734        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10735            throw new SecurityException("killProcessesBelowForeground() only available to system");
10736        }
10737
10738        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10739    }
10740
10741    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10742        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10743            throw new SecurityException("killProcessesBelowAdj() only available to system");
10744        }
10745
10746        boolean killed = false;
10747        synchronized (mPidsSelfLocked) {
10748            final int size = mPidsSelfLocked.size();
10749            for (int i = 0; i < size; i++) {
10750                final int pid = mPidsSelfLocked.keyAt(i);
10751                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10752                if (proc == null) continue;
10753
10754                final int adj = proc.setAdj;
10755                if (adj > belowAdj && !proc.killedByAm) {
10756                    proc.kill(reason, true);
10757                    killed = true;
10758                }
10759            }
10760        }
10761        return killed;
10762    }
10763
10764    @Override
10765    public void hang(final IBinder who, boolean allowRestart) {
10766        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10767                != PackageManager.PERMISSION_GRANTED) {
10768            throw new SecurityException("Requires permission "
10769                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10770        }
10771
10772        final IBinder.DeathRecipient death = new DeathRecipient() {
10773            @Override
10774            public void binderDied() {
10775                synchronized (this) {
10776                    notifyAll();
10777                }
10778            }
10779        };
10780
10781        try {
10782            who.linkToDeath(death, 0);
10783        } catch (RemoteException e) {
10784            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10785            return;
10786        }
10787
10788        synchronized (this) {
10789            Watchdog.getInstance().setAllowRestart(allowRestart);
10790            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10791            synchronized (death) {
10792                while (who.isBinderAlive()) {
10793                    try {
10794                        death.wait();
10795                    } catch (InterruptedException e) {
10796                    }
10797                }
10798            }
10799            Watchdog.getInstance().setAllowRestart(true);
10800        }
10801    }
10802
10803    @Override
10804    public void restart() {
10805        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10806                != PackageManager.PERMISSION_GRANTED) {
10807            throw new SecurityException("Requires permission "
10808                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10809        }
10810
10811        Log.i(TAG, "Sending shutdown broadcast...");
10812
10813        BroadcastReceiver br = new BroadcastReceiver() {
10814            @Override public void onReceive(Context context, Intent intent) {
10815                // Now the broadcast is done, finish up the low-level shutdown.
10816                Log.i(TAG, "Shutting down activity manager...");
10817                shutdown(10000);
10818                Log.i(TAG, "Shutdown complete, restarting!");
10819                Process.killProcess(Process.myPid());
10820                System.exit(10);
10821            }
10822        };
10823
10824        // First send the high-level shut down broadcast.
10825        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10826        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10827        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10828        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10829        mContext.sendOrderedBroadcastAsUser(intent,
10830                UserHandle.ALL, null, br, mHandler, 0, null, null);
10831        */
10832        br.onReceive(mContext, intent);
10833    }
10834
10835    private long getLowRamTimeSinceIdle(long now) {
10836        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10837    }
10838
10839    @Override
10840    public void performIdleMaintenance() {
10841        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10842                != PackageManager.PERMISSION_GRANTED) {
10843            throw new SecurityException("Requires permission "
10844                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10845        }
10846
10847        synchronized (this) {
10848            final long now = SystemClock.uptimeMillis();
10849            final long timeSinceLastIdle = now - mLastIdleTime;
10850            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10851            mLastIdleTime = now;
10852            mLowRamTimeSinceLastIdle = 0;
10853            if (mLowRamStartTime != 0) {
10854                mLowRamStartTime = now;
10855            }
10856
10857            StringBuilder sb = new StringBuilder(128);
10858            sb.append("Idle maintenance over ");
10859            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10860            sb.append(" low RAM for ");
10861            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10862            Slog.i(TAG, sb.toString());
10863
10864            // If at least 1/3 of our time since the last idle period has been spent
10865            // with RAM low, then we want to kill processes.
10866            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10867
10868            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10869                ProcessRecord proc = mLruProcesses.get(i);
10870                if (proc.notCachedSinceIdle) {
10871                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10872                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10873                        if (doKilling && proc.initialIdlePss != 0
10874                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10875                            proc.kill("idle maint (pss " + proc.lastPss
10876                                    + " from " + proc.initialIdlePss + ")", true);
10877                        }
10878                    }
10879                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10880                    proc.notCachedSinceIdle = true;
10881                    proc.initialIdlePss = 0;
10882                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10883                            isSleeping(), now);
10884                }
10885            }
10886
10887            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10888            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10889        }
10890    }
10891
10892    private void retrieveSettings() {
10893        final ContentResolver resolver = mContext.getContentResolver();
10894        String debugApp = Settings.Global.getString(
10895            resolver, Settings.Global.DEBUG_APP);
10896        boolean waitForDebugger = Settings.Global.getInt(
10897            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10898        boolean alwaysFinishActivities = Settings.Global.getInt(
10899            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10900        boolean forceRtl = Settings.Global.getInt(
10901                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10902        // Transfer any global setting for forcing RTL layout, into a System Property
10903        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10904
10905        Configuration configuration = new Configuration();
10906        Settings.System.getConfiguration(resolver, configuration);
10907        if (forceRtl) {
10908            // This will take care of setting the correct layout direction flags
10909            configuration.setLayoutDirection(configuration.locale);
10910        }
10911
10912        synchronized (this) {
10913            mDebugApp = mOrigDebugApp = debugApp;
10914            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10915            mAlwaysFinishActivities = alwaysFinishActivities;
10916            // This happens before any activities are started, so we can
10917            // change mConfiguration in-place.
10918            updateConfigurationLocked(configuration, null, false, true);
10919            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10920        }
10921    }
10922
10923    /** Loads resources after the current configuration has been set. */
10924    private void loadResourcesOnSystemReady() {
10925        final Resources res = mContext.getResources();
10926        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10927        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10928        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10929    }
10930
10931    public boolean testIsSystemReady() {
10932        // no need to synchronize(this) just to read & return the value
10933        return mSystemReady;
10934    }
10935
10936    private static File getCalledPreBootReceiversFile() {
10937        File dataDir = Environment.getDataDirectory();
10938        File systemDir = new File(dataDir, "system");
10939        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10940        return fname;
10941    }
10942
10943    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10944        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10945        File file = getCalledPreBootReceiversFile();
10946        FileInputStream fis = null;
10947        try {
10948            fis = new FileInputStream(file);
10949            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10950            int fvers = dis.readInt();
10951            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10952                String vers = dis.readUTF();
10953                String codename = dis.readUTF();
10954                String build = dis.readUTF();
10955                if (android.os.Build.VERSION.RELEASE.equals(vers)
10956                        && android.os.Build.VERSION.CODENAME.equals(codename)
10957                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10958                    int num = dis.readInt();
10959                    while (num > 0) {
10960                        num--;
10961                        String pkg = dis.readUTF();
10962                        String cls = dis.readUTF();
10963                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10964                    }
10965                }
10966            }
10967        } catch (FileNotFoundException e) {
10968        } catch (IOException e) {
10969            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10970        } finally {
10971            if (fis != null) {
10972                try {
10973                    fis.close();
10974                } catch (IOException e) {
10975                }
10976            }
10977        }
10978        return lastDoneReceivers;
10979    }
10980
10981    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10982        File file = getCalledPreBootReceiversFile();
10983        FileOutputStream fos = null;
10984        DataOutputStream dos = null;
10985        try {
10986            fos = new FileOutputStream(file);
10987            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10988            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10989            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10990            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10991            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10992            dos.writeInt(list.size());
10993            for (int i=0; i<list.size(); i++) {
10994                dos.writeUTF(list.get(i).getPackageName());
10995                dos.writeUTF(list.get(i).getClassName());
10996            }
10997        } catch (IOException e) {
10998            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10999            file.delete();
11000        } finally {
11001            FileUtils.sync(fos);
11002            if (dos != null) {
11003                try {
11004                    dos.close();
11005                } catch (IOException e) {
11006                    // TODO Auto-generated catch block
11007                    e.printStackTrace();
11008                }
11009            }
11010        }
11011    }
11012
11013    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11014            ArrayList<ComponentName> doneReceivers, int userId) {
11015        boolean waitingUpdate = false;
11016        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11017        List<ResolveInfo> ris = null;
11018        try {
11019            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11020                    intent, null, 0, userId);
11021        } catch (RemoteException e) {
11022        }
11023        if (ris != null) {
11024            for (int i=ris.size()-1; i>=0; i--) {
11025                if ((ris.get(i).activityInfo.applicationInfo.flags
11026                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11027                    ris.remove(i);
11028                }
11029            }
11030            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11031
11032            // For User 0, load the version number. When delivering to a new user, deliver
11033            // to all receivers.
11034            if (userId == UserHandle.USER_OWNER) {
11035                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11036                for (int i=0; i<ris.size(); i++) {
11037                    ActivityInfo ai = ris.get(i).activityInfo;
11038                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11039                    if (lastDoneReceivers.contains(comp)) {
11040                        // We already did the pre boot receiver for this app with the current
11041                        // platform version, so don't do it again...
11042                        ris.remove(i);
11043                        i--;
11044                        // ...however, do keep it as one that has been done, so we don't
11045                        // forget about it when rewriting the file of last done receivers.
11046                        doneReceivers.add(comp);
11047                    }
11048                }
11049            }
11050
11051            // If primary user, send broadcast to all available users, else just to userId
11052            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11053                    : new int[] { userId };
11054            for (int i = 0; i < ris.size(); i++) {
11055                ActivityInfo ai = ris.get(i).activityInfo;
11056                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11057                doneReceivers.add(comp);
11058                intent.setComponent(comp);
11059                for (int j=0; j<users.length; j++) {
11060                    IIntentReceiver finisher = null;
11061                    // On last receiver and user, set up a completion callback
11062                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11063                        finisher = new IIntentReceiver.Stub() {
11064                            public void performReceive(Intent intent, int resultCode,
11065                                    String data, Bundle extras, boolean ordered,
11066                                    boolean sticky, int sendingUser) {
11067                                // The raw IIntentReceiver interface is called
11068                                // with the AM lock held, so redispatch to
11069                                // execute our code without the lock.
11070                                mHandler.post(onFinishCallback);
11071                            }
11072                        };
11073                    }
11074                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11075                            + " for user " + users[j]);
11076                    broadcastIntentLocked(null, null, intent, null, finisher,
11077                            0, null, null, null, AppOpsManager.OP_NONE,
11078                            true, false, MY_PID, Process.SYSTEM_UID,
11079                            users[j]);
11080                    if (finisher != null) {
11081                        waitingUpdate = true;
11082                    }
11083                }
11084            }
11085        }
11086
11087        return waitingUpdate;
11088    }
11089
11090    public void systemReady(final Runnable goingCallback) {
11091        synchronized(this) {
11092            if (mSystemReady) {
11093                // If we're done calling all the receivers, run the next "boot phase" passed in
11094                // by the SystemServer
11095                if (goingCallback != null) {
11096                    goingCallback.run();
11097                }
11098                return;
11099            }
11100
11101            // Make sure we have the current profile info, since it is needed for
11102            // security checks.
11103            updateCurrentProfileIdsLocked();
11104
11105            if (mRecentTasks == null) {
11106                mRecentTasks = mTaskPersister.restoreTasksLocked();
11107                if (!mRecentTasks.isEmpty()) {
11108                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11109                }
11110                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11111                mTaskPersister.startPersisting();
11112            }
11113
11114            // Check to see if there are any update receivers to run.
11115            if (!mDidUpdate) {
11116                if (mWaitingUpdate) {
11117                    return;
11118                }
11119                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11120                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11121                    public void run() {
11122                        synchronized (ActivityManagerService.this) {
11123                            mDidUpdate = true;
11124                        }
11125                        writeLastDonePreBootReceivers(doneReceivers);
11126                        showBootMessage(mContext.getText(
11127                                R.string.android_upgrading_complete),
11128                                false);
11129                        systemReady(goingCallback);
11130                    }
11131                }, doneReceivers, UserHandle.USER_OWNER);
11132
11133                if (mWaitingUpdate) {
11134                    return;
11135                }
11136                mDidUpdate = true;
11137            }
11138
11139            mAppOpsService.systemReady();
11140            mSystemReady = true;
11141        }
11142
11143        ArrayList<ProcessRecord> procsToKill = null;
11144        synchronized(mPidsSelfLocked) {
11145            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11146                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11147                if (!isAllowedWhileBooting(proc.info)){
11148                    if (procsToKill == null) {
11149                        procsToKill = new ArrayList<ProcessRecord>();
11150                    }
11151                    procsToKill.add(proc);
11152                }
11153            }
11154        }
11155
11156        synchronized(this) {
11157            if (procsToKill != null) {
11158                for (int i=procsToKill.size()-1; i>=0; i--) {
11159                    ProcessRecord proc = procsToKill.get(i);
11160                    Slog.i(TAG, "Removing system update proc: " + proc);
11161                    removeProcessLocked(proc, true, false, "system update done");
11162                }
11163            }
11164
11165            // Now that we have cleaned up any update processes, we
11166            // are ready to start launching real processes and know that
11167            // we won't trample on them any more.
11168            mProcessesReady = true;
11169        }
11170
11171        Slog.i(TAG, "System now ready");
11172        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11173            SystemClock.uptimeMillis());
11174
11175        synchronized(this) {
11176            // Make sure we have no pre-ready processes sitting around.
11177
11178            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11179                ResolveInfo ri = mContext.getPackageManager()
11180                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11181                                STOCK_PM_FLAGS);
11182                CharSequence errorMsg = null;
11183                if (ri != null) {
11184                    ActivityInfo ai = ri.activityInfo;
11185                    ApplicationInfo app = ai.applicationInfo;
11186                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11187                        mTopAction = Intent.ACTION_FACTORY_TEST;
11188                        mTopData = null;
11189                        mTopComponent = new ComponentName(app.packageName,
11190                                ai.name);
11191                    } else {
11192                        errorMsg = mContext.getResources().getText(
11193                                com.android.internal.R.string.factorytest_not_system);
11194                    }
11195                } else {
11196                    errorMsg = mContext.getResources().getText(
11197                            com.android.internal.R.string.factorytest_no_action);
11198                }
11199                if (errorMsg != null) {
11200                    mTopAction = null;
11201                    mTopData = null;
11202                    mTopComponent = null;
11203                    Message msg = Message.obtain();
11204                    msg.what = SHOW_FACTORY_ERROR_MSG;
11205                    msg.getData().putCharSequence("msg", errorMsg);
11206                    mHandler.sendMessage(msg);
11207                }
11208            }
11209        }
11210
11211        retrieveSettings();
11212        loadResourcesOnSystemReady();
11213
11214        synchronized (this) {
11215            readGrantedUriPermissionsLocked();
11216        }
11217
11218        if (goingCallback != null) goingCallback.run();
11219
11220        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11221                Integer.toString(mCurrentUserId), mCurrentUserId);
11222        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11223                Integer.toString(mCurrentUserId), mCurrentUserId);
11224        mSystemServiceManager.startUser(mCurrentUserId);
11225
11226        synchronized (this) {
11227            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11228                try {
11229                    List apps = AppGlobals.getPackageManager().
11230                        getPersistentApplications(STOCK_PM_FLAGS);
11231                    if (apps != null) {
11232                        int N = apps.size();
11233                        int i;
11234                        for (i=0; i<N; i++) {
11235                            ApplicationInfo info
11236                                = (ApplicationInfo)apps.get(i);
11237                            if (info != null &&
11238                                    !info.packageName.equals("android")) {
11239                                addAppLocked(info, false, null /* ABI override */);
11240                            }
11241                        }
11242                    }
11243                } catch (RemoteException ex) {
11244                    // pm is in same process, this will never happen.
11245                }
11246            }
11247
11248            // Start up initial activity.
11249            mBooting = true;
11250            startHomeActivityLocked(mCurrentUserId);
11251
11252            try {
11253                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11254                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11255                            + " data partition or your device will be unstable.");
11256                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11257                }
11258            } catch (RemoteException e) {
11259            }
11260
11261            if (!Build.isFingerprintConsistent()) {
11262                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11263                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11264            }
11265
11266            long ident = Binder.clearCallingIdentity();
11267            try {
11268                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11269                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11270                        | Intent.FLAG_RECEIVER_FOREGROUND);
11271                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11272                broadcastIntentLocked(null, null, intent,
11273                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11274                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11275                intent = new Intent(Intent.ACTION_USER_STARTING);
11276                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11277                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11278                broadcastIntentLocked(null, null, intent,
11279                        null, new IIntentReceiver.Stub() {
11280                            @Override
11281                            public void performReceive(Intent intent, int resultCode, String data,
11282                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11283                                    throws RemoteException {
11284                            }
11285                        }, 0, null, null,
11286                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11287                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11288            } catch (Throwable t) {
11289                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11290            } finally {
11291                Binder.restoreCallingIdentity(ident);
11292            }
11293            mStackSupervisor.resumeTopActivitiesLocked();
11294            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11295        }
11296    }
11297
11298    private boolean makeAppCrashingLocked(ProcessRecord app,
11299            String shortMsg, String longMsg, String stackTrace) {
11300        app.crashing = true;
11301        app.crashingReport = generateProcessError(app,
11302                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11303        startAppProblemLocked(app);
11304        app.stopFreezingAllLocked();
11305        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11306    }
11307
11308    private void makeAppNotRespondingLocked(ProcessRecord app,
11309            String activity, String shortMsg, String longMsg) {
11310        app.notResponding = true;
11311        app.notRespondingReport = generateProcessError(app,
11312                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11313                activity, shortMsg, longMsg, null);
11314        startAppProblemLocked(app);
11315        app.stopFreezingAllLocked();
11316    }
11317
11318    /**
11319     * Generate a process error record, suitable for attachment to a ProcessRecord.
11320     *
11321     * @param app The ProcessRecord in which the error occurred.
11322     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11323     *                      ActivityManager.AppErrorStateInfo
11324     * @param activity The activity associated with the crash, if known.
11325     * @param shortMsg Short message describing the crash.
11326     * @param longMsg Long message describing the crash.
11327     * @param stackTrace Full crash stack trace, may be null.
11328     *
11329     * @return Returns a fully-formed AppErrorStateInfo record.
11330     */
11331    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11332            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11333        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11334
11335        report.condition = condition;
11336        report.processName = app.processName;
11337        report.pid = app.pid;
11338        report.uid = app.info.uid;
11339        report.tag = activity;
11340        report.shortMsg = shortMsg;
11341        report.longMsg = longMsg;
11342        report.stackTrace = stackTrace;
11343
11344        return report;
11345    }
11346
11347    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11348        synchronized (this) {
11349            app.crashing = false;
11350            app.crashingReport = null;
11351            app.notResponding = false;
11352            app.notRespondingReport = null;
11353            if (app.anrDialog == fromDialog) {
11354                app.anrDialog = null;
11355            }
11356            if (app.waitDialog == fromDialog) {
11357                app.waitDialog = null;
11358            }
11359            if (app.pid > 0 && app.pid != MY_PID) {
11360                handleAppCrashLocked(app, null, null, null);
11361                app.kill("user request after error", true);
11362            }
11363        }
11364    }
11365
11366    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11367            String stackTrace) {
11368        long now = SystemClock.uptimeMillis();
11369
11370        Long crashTime;
11371        if (!app.isolated) {
11372            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11373        } else {
11374            crashTime = null;
11375        }
11376        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11377            // This process loses!
11378            Slog.w(TAG, "Process " + app.info.processName
11379                    + " has crashed too many times: killing!");
11380            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11381                    app.userId, app.info.processName, app.uid);
11382            mStackSupervisor.handleAppCrashLocked(app);
11383            if (!app.persistent) {
11384                // We don't want to start this process again until the user
11385                // explicitly does so...  but for persistent process, we really
11386                // need to keep it running.  If a persistent process is actually
11387                // repeatedly crashing, then badness for everyone.
11388                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11389                        app.info.processName);
11390                if (!app.isolated) {
11391                    // XXX We don't have a way to mark isolated processes
11392                    // as bad, since they don't have a peristent identity.
11393                    mBadProcesses.put(app.info.processName, app.uid,
11394                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11395                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11396                }
11397                app.bad = true;
11398                app.removed = true;
11399                // Don't let services in this process be restarted and potentially
11400                // annoy the user repeatedly.  Unless it is persistent, since those
11401                // processes run critical code.
11402                removeProcessLocked(app, false, false, "crash");
11403                mStackSupervisor.resumeTopActivitiesLocked();
11404                return false;
11405            }
11406            mStackSupervisor.resumeTopActivitiesLocked();
11407        } else {
11408            mStackSupervisor.finishTopRunningActivityLocked(app);
11409        }
11410
11411        // Bump up the crash count of any services currently running in the proc.
11412        for (int i=app.services.size()-1; i>=0; i--) {
11413            // Any services running in the application need to be placed
11414            // back in the pending list.
11415            ServiceRecord sr = app.services.valueAt(i);
11416            sr.crashCount++;
11417        }
11418
11419        // If the crashing process is what we consider to be the "home process" and it has been
11420        // replaced by a third-party app, clear the package preferred activities from packages
11421        // with a home activity running in the process to prevent a repeatedly crashing app
11422        // from blocking the user to manually clear the list.
11423        final ArrayList<ActivityRecord> activities = app.activities;
11424        if (app == mHomeProcess && activities.size() > 0
11425                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11426            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11427                final ActivityRecord r = activities.get(activityNdx);
11428                if (r.isHomeActivity()) {
11429                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11430                    try {
11431                        ActivityThread.getPackageManager()
11432                                .clearPackagePreferredActivities(r.packageName);
11433                    } catch (RemoteException c) {
11434                        // pm is in same process, this will never happen.
11435                    }
11436                }
11437            }
11438        }
11439
11440        if (!app.isolated) {
11441            // XXX Can't keep track of crash times for isolated processes,
11442            // because they don't have a perisistent identity.
11443            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11444        }
11445
11446        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11447        return true;
11448    }
11449
11450    void startAppProblemLocked(ProcessRecord app) {
11451        // If this app is not running under the current user, then we
11452        // can't give it a report button because that would require
11453        // launching the report UI under a different user.
11454        app.errorReportReceiver = null;
11455
11456        for (int userId : mCurrentProfileIds) {
11457            if (app.userId == userId) {
11458                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11459                        mContext, app.info.packageName, app.info.flags);
11460            }
11461        }
11462        skipCurrentReceiverLocked(app);
11463    }
11464
11465    void skipCurrentReceiverLocked(ProcessRecord app) {
11466        for (BroadcastQueue queue : mBroadcastQueues) {
11467            queue.skipCurrentReceiverLocked(app);
11468        }
11469    }
11470
11471    /**
11472     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11473     * The application process will exit immediately after this call returns.
11474     * @param app object of the crashing app, null for the system server
11475     * @param crashInfo describing the exception
11476     */
11477    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11478        ProcessRecord r = findAppProcess(app, "Crash");
11479        final String processName = app == null ? "system_server"
11480                : (r == null ? "unknown" : r.processName);
11481
11482        handleApplicationCrashInner("crash", r, processName, crashInfo);
11483    }
11484
11485    /* Native crash reporting uses this inner version because it needs to be somewhat
11486     * decoupled from the AM-managed cleanup lifecycle
11487     */
11488    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11489            ApplicationErrorReport.CrashInfo crashInfo) {
11490        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11491                UserHandle.getUserId(Binder.getCallingUid()), processName,
11492                r == null ? -1 : r.info.flags,
11493                crashInfo.exceptionClassName,
11494                crashInfo.exceptionMessage,
11495                crashInfo.throwFileName,
11496                crashInfo.throwLineNumber);
11497
11498        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11499
11500        crashApplication(r, crashInfo);
11501    }
11502
11503    public void handleApplicationStrictModeViolation(
11504            IBinder app,
11505            int violationMask,
11506            StrictMode.ViolationInfo info) {
11507        ProcessRecord r = findAppProcess(app, "StrictMode");
11508        if (r == null) {
11509            return;
11510        }
11511
11512        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11513            Integer stackFingerprint = info.hashCode();
11514            boolean logIt = true;
11515            synchronized (mAlreadyLoggedViolatedStacks) {
11516                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11517                    logIt = false;
11518                    // TODO: sub-sample into EventLog for these, with
11519                    // the info.durationMillis?  Then we'd get
11520                    // the relative pain numbers, without logging all
11521                    // the stack traces repeatedly.  We'd want to do
11522                    // likewise in the client code, which also does
11523                    // dup suppression, before the Binder call.
11524                } else {
11525                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11526                        mAlreadyLoggedViolatedStacks.clear();
11527                    }
11528                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11529                }
11530            }
11531            if (logIt) {
11532                logStrictModeViolationToDropBox(r, info);
11533            }
11534        }
11535
11536        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11537            AppErrorResult result = new AppErrorResult();
11538            synchronized (this) {
11539                final long origId = Binder.clearCallingIdentity();
11540
11541                Message msg = Message.obtain();
11542                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11543                HashMap<String, Object> data = new HashMap<String, Object>();
11544                data.put("result", result);
11545                data.put("app", r);
11546                data.put("violationMask", violationMask);
11547                data.put("info", info);
11548                msg.obj = data;
11549                mHandler.sendMessage(msg);
11550
11551                Binder.restoreCallingIdentity(origId);
11552            }
11553            int res = result.get();
11554            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11555        }
11556    }
11557
11558    // Depending on the policy in effect, there could be a bunch of
11559    // these in quick succession so we try to batch these together to
11560    // minimize disk writes, number of dropbox entries, and maximize
11561    // compression, by having more fewer, larger records.
11562    private void logStrictModeViolationToDropBox(
11563            ProcessRecord process,
11564            StrictMode.ViolationInfo info) {
11565        if (info == null) {
11566            return;
11567        }
11568        final boolean isSystemApp = process == null ||
11569                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11570                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11571        final String processName = process == null ? "unknown" : process.processName;
11572        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11573        final DropBoxManager dbox = (DropBoxManager)
11574                mContext.getSystemService(Context.DROPBOX_SERVICE);
11575
11576        // Exit early if the dropbox isn't configured to accept this report type.
11577        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11578
11579        boolean bufferWasEmpty;
11580        boolean needsFlush;
11581        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11582        synchronized (sb) {
11583            bufferWasEmpty = sb.length() == 0;
11584            appendDropBoxProcessHeaders(process, processName, sb);
11585            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11586            sb.append("System-App: ").append(isSystemApp).append("\n");
11587            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11588            if (info.violationNumThisLoop != 0) {
11589                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11590            }
11591            if (info.numAnimationsRunning != 0) {
11592                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11593            }
11594            if (info.broadcastIntentAction != null) {
11595                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11596            }
11597            if (info.durationMillis != -1) {
11598                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11599            }
11600            if (info.numInstances != -1) {
11601                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11602            }
11603            if (info.tags != null) {
11604                for (String tag : info.tags) {
11605                    sb.append("Span-Tag: ").append(tag).append("\n");
11606                }
11607            }
11608            sb.append("\n");
11609            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11610                sb.append(info.crashInfo.stackTrace);
11611            }
11612            sb.append("\n");
11613
11614            // Only buffer up to ~64k.  Various logging bits truncate
11615            // things at 128k.
11616            needsFlush = (sb.length() > 64 * 1024);
11617        }
11618
11619        // Flush immediately if the buffer's grown too large, or this
11620        // is a non-system app.  Non-system apps are isolated with a
11621        // different tag & policy and not batched.
11622        //
11623        // Batching is useful during internal testing with
11624        // StrictMode settings turned up high.  Without batching,
11625        // thousands of separate files could be created on boot.
11626        if (!isSystemApp || needsFlush) {
11627            new Thread("Error dump: " + dropboxTag) {
11628                @Override
11629                public void run() {
11630                    String report;
11631                    synchronized (sb) {
11632                        report = sb.toString();
11633                        sb.delete(0, sb.length());
11634                        sb.trimToSize();
11635                    }
11636                    if (report.length() != 0) {
11637                        dbox.addText(dropboxTag, report);
11638                    }
11639                }
11640            }.start();
11641            return;
11642        }
11643
11644        // System app batching:
11645        if (!bufferWasEmpty) {
11646            // An existing dropbox-writing thread is outstanding, so
11647            // we don't need to start it up.  The existing thread will
11648            // catch the buffer appends we just did.
11649            return;
11650        }
11651
11652        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11653        // (After this point, we shouldn't access AMS internal data structures.)
11654        new Thread("Error dump: " + dropboxTag) {
11655            @Override
11656            public void run() {
11657                // 5 second sleep to let stacks arrive and be batched together
11658                try {
11659                    Thread.sleep(5000);  // 5 seconds
11660                } catch (InterruptedException e) {}
11661
11662                String errorReport;
11663                synchronized (mStrictModeBuffer) {
11664                    errorReport = mStrictModeBuffer.toString();
11665                    if (errorReport.length() == 0) {
11666                        return;
11667                    }
11668                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11669                    mStrictModeBuffer.trimToSize();
11670                }
11671                dbox.addText(dropboxTag, errorReport);
11672            }
11673        }.start();
11674    }
11675
11676    /**
11677     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11678     * @param app object of the crashing app, null for the system server
11679     * @param tag reported by the caller
11680     * @param system whether this wtf is coming from the system
11681     * @param crashInfo describing the context of the error
11682     * @return true if the process should exit immediately (WTF is fatal)
11683     */
11684    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11685            final ApplicationErrorReport.CrashInfo crashInfo) {
11686        final int callingUid = Binder.getCallingUid();
11687        final int callingPid = Binder.getCallingPid();
11688
11689        if (system) {
11690            // If this is coming from the system, we could very well have low-level
11691            // system locks held, so we want to do this all asynchronously.  And we
11692            // never want this to become fatal, so there is that too.
11693            mHandler.post(new Runnable() {
11694                @Override public void run() {
11695                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11696                }
11697            });
11698            return false;
11699        }
11700
11701        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11702                crashInfo);
11703
11704        if (r != null && r.pid != Process.myPid() &&
11705                Settings.Global.getInt(mContext.getContentResolver(),
11706                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11707            crashApplication(r, crashInfo);
11708            return true;
11709        } else {
11710            return false;
11711        }
11712    }
11713
11714    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11715            final ApplicationErrorReport.CrashInfo crashInfo) {
11716        final ProcessRecord r = findAppProcess(app, "WTF");
11717        final String processName = app == null ? "system_server"
11718                : (r == null ? "unknown" : r.processName);
11719
11720        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11721                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11722
11723        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11724
11725        return r;
11726    }
11727
11728    /**
11729     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11730     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11731     */
11732    private ProcessRecord findAppProcess(IBinder app, String reason) {
11733        if (app == null) {
11734            return null;
11735        }
11736
11737        synchronized (this) {
11738            final int NP = mProcessNames.getMap().size();
11739            for (int ip=0; ip<NP; ip++) {
11740                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11741                final int NA = apps.size();
11742                for (int ia=0; ia<NA; ia++) {
11743                    ProcessRecord p = apps.valueAt(ia);
11744                    if (p.thread != null && p.thread.asBinder() == app) {
11745                        return p;
11746                    }
11747                }
11748            }
11749
11750            Slog.w(TAG, "Can't find mystery application for " + reason
11751                    + " from pid=" + Binder.getCallingPid()
11752                    + " uid=" + Binder.getCallingUid() + ": " + app);
11753            return null;
11754        }
11755    }
11756
11757    /**
11758     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11759     * to append various headers to the dropbox log text.
11760     */
11761    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11762            StringBuilder sb) {
11763        // Watchdog thread ends up invoking this function (with
11764        // a null ProcessRecord) to add the stack file to dropbox.
11765        // Do not acquire a lock on this (am) in such cases, as it
11766        // could cause a potential deadlock, if and when watchdog
11767        // is invoked due to unavailability of lock on am and it
11768        // would prevent watchdog from killing system_server.
11769        if (process == null) {
11770            sb.append("Process: ").append(processName).append("\n");
11771            return;
11772        }
11773        // Note: ProcessRecord 'process' is guarded by the service
11774        // instance.  (notably process.pkgList, which could otherwise change
11775        // concurrently during execution of this method)
11776        synchronized (this) {
11777            sb.append("Process: ").append(processName).append("\n");
11778            int flags = process.info.flags;
11779            IPackageManager pm = AppGlobals.getPackageManager();
11780            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11781            for (int ip=0; ip<process.pkgList.size(); ip++) {
11782                String pkg = process.pkgList.keyAt(ip);
11783                sb.append("Package: ").append(pkg);
11784                try {
11785                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11786                    if (pi != null) {
11787                        sb.append(" v").append(pi.versionCode);
11788                        if (pi.versionName != null) {
11789                            sb.append(" (").append(pi.versionName).append(")");
11790                        }
11791                    }
11792                } catch (RemoteException e) {
11793                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11794                }
11795                sb.append("\n");
11796            }
11797        }
11798    }
11799
11800    private static String processClass(ProcessRecord process) {
11801        if (process == null || process.pid == MY_PID) {
11802            return "system_server";
11803        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11804            return "system_app";
11805        } else {
11806            return "data_app";
11807        }
11808    }
11809
11810    /**
11811     * Write a description of an error (crash, WTF, ANR) to the drop box.
11812     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11813     * @param process which caused the error, null means the system server
11814     * @param activity which triggered the error, null if unknown
11815     * @param parent activity related to the error, null if unknown
11816     * @param subject line related to the error, null if absent
11817     * @param report in long form describing the error, null if absent
11818     * @param logFile to include in the report, null if none
11819     * @param crashInfo giving an application stack trace, null if absent
11820     */
11821    public void addErrorToDropBox(String eventType,
11822            ProcessRecord process, String processName, ActivityRecord activity,
11823            ActivityRecord parent, String subject,
11824            final String report, final File logFile,
11825            final ApplicationErrorReport.CrashInfo crashInfo) {
11826        // NOTE -- this must never acquire the ActivityManagerService lock,
11827        // otherwise the watchdog may be prevented from resetting the system.
11828
11829        final String dropboxTag = processClass(process) + "_" + eventType;
11830        final DropBoxManager dbox = (DropBoxManager)
11831                mContext.getSystemService(Context.DROPBOX_SERVICE);
11832
11833        // Exit early if the dropbox isn't configured to accept this report type.
11834        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11835
11836        final StringBuilder sb = new StringBuilder(1024);
11837        appendDropBoxProcessHeaders(process, processName, sb);
11838        if (activity != null) {
11839            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11840        }
11841        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11842            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11843        }
11844        if (parent != null && parent != activity) {
11845            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11846        }
11847        if (subject != null) {
11848            sb.append("Subject: ").append(subject).append("\n");
11849        }
11850        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11851        if (Debug.isDebuggerConnected()) {
11852            sb.append("Debugger: Connected\n");
11853        }
11854        sb.append("\n");
11855
11856        // Do the rest in a worker thread to avoid blocking the caller on I/O
11857        // (After this point, we shouldn't access AMS internal data structures.)
11858        Thread worker = new Thread("Error dump: " + dropboxTag) {
11859            @Override
11860            public void run() {
11861                if (report != null) {
11862                    sb.append(report);
11863                }
11864                if (logFile != null) {
11865                    try {
11866                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11867                                    "\n\n[[TRUNCATED]]"));
11868                    } catch (IOException e) {
11869                        Slog.e(TAG, "Error reading " + logFile, e);
11870                    }
11871                }
11872                if (crashInfo != null && crashInfo.stackTrace != null) {
11873                    sb.append(crashInfo.stackTrace);
11874                }
11875
11876                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11877                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11878                if (lines > 0) {
11879                    sb.append("\n");
11880
11881                    // Merge several logcat streams, and take the last N lines
11882                    InputStreamReader input = null;
11883                    try {
11884                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11885                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11886                                "-b", "crash",
11887                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11888
11889                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11890                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11891                        input = new InputStreamReader(logcat.getInputStream());
11892
11893                        int num;
11894                        char[] buf = new char[8192];
11895                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11896                    } catch (IOException e) {
11897                        Slog.e(TAG, "Error running logcat", e);
11898                    } finally {
11899                        if (input != null) try { input.close(); } catch (IOException e) {}
11900                    }
11901                }
11902
11903                dbox.addText(dropboxTag, sb.toString());
11904            }
11905        };
11906
11907        if (process == null) {
11908            // If process is null, we are being called from some internal code
11909            // and may be about to die -- run this synchronously.
11910            worker.run();
11911        } else {
11912            worker.start();
11913        }
11914    }
11915
11916    /**
11917     * Bring up the "unexpected error" dialog box for a crashing app.
11918     * Deal with edge cases (intercepts from instrumented applications,
11919     * ActivityController, error intent receivers, that sort of thing).
11920     * @param r the application crashing
11921     * @param crashInfo describing the failure
11922     */
11923    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11924        long timeMillis = System.currentTimeMillis();
11925        String shortMsg = crashInfo.exceptionClassName;
11926        String longMsg = crashInfo.exceptionMessage;
11927        String stackTrace = crashInfo.stackTrace;
11928        if (shortMsg != null && longMsg != null) {
11929            longMsg = shortMsg + ": " + longMsg;
11930        } else if (shortMsg != null) {
11931            longMsg = shortMsg;
11932        }
11933
11934        AppErrorResult result = new AppErrorResult();
11935        synchronized (this) {
11936            if (mController != null) {
11937                try {
11938                    String name = r != null ? r.processName : null;
11939                    int pid = r != null ? r.pid : Binder.getCallingPid();
11940                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11941                    if (!mController.appCrashed(name, pid,
11942                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11943                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11944                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11945                            Slog.w(TAG, "Skip killing native crashed app " + name
11946                                    + "(" + pid + ") during testing");
11947                        } else {
11948                            Slog.w(TAG, "Force-killing crashed app " + name
11949                                    + " at watcher's request");
11950                            if (r != null) {
11951                                r.kill("crash", true);
11952                            } else {
11953                                // Huh.
11954                                Process.killProcess(pid);
11955                                Process.killProcessGroup(uid, pid);
11956                            }
11957                        }
11958                        return;
11959                    }
11960                } catch (RemoteException e) {
11961                    mController = null;
11962                    Watchdog.getInstance().setActivityController(null);
11963                }
11964            }
11965
11966            final long origId = Binder.clearCallingIdentity();
11967
11968            // If this process is running instrumentation, finish it.
11969            if (r != null && r.instrumentationClass != null) {
11970                Slog.w(TAG, "Error in app " + r.processName
11971                      + " running instrumentation " + r.instrumentationClass + ":");
11972                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11973                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11974                Bundle info = new Bundle();
11975                info.putString("shortMsg", shortMsg);
11976                info.putString("longMsg", longMsg);
11977                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11978                Binder.restoreCallingIdentity(origId);
11979                return;
11980            }
11981
11982            // If we can't identify the process or it's already exceeded its crash quota,
11983            // quit right away without showing a crash dialog.
11984            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11985                Binder.restoreCallingIdentity(origId);
11986                return;
11987            }
11988
11989            Message msg = Message.obtain();
11990            msg.what = SHOW_ERROR_MSG;
11991            HashMap data = new HashMap();
11992            data.put("result", result);
11993            data.put("app", r);
11994            msg.obj = data;
11995            mHandler.sendMessage(msg);
11996
11997            Binder.restoreCallingIdentity(origId);
11998        }
11999
12000        int res = result.get();
12001
12002        Intent appErrorIntent = null;
12003        synchronized (this) {
12004            if (r != null && !r.isolated) {
12005                // XXX Can't keep track of crash time for isolated processes,
12006                // since they don't have a persistent identity.
12007                mProcessCrashTimes.put(r.info.processName, r.uid,
12008                        SystemClock.uptimeMillis());
12009            }
12010            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12011                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12012            }
12013        }
12014
12015        if (appErrorIntent != null) {
12016            try {
12017                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12018            } catch (ActivityNotFoundException e) {
12019                Slog.w(TAG, "bug report receiver dissappeared", e);
12020            }
12021        }
12022    }
12023
12024    Intent createAppErrorIntentLocked(ProcessRecord r,
12025            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12026        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12027        if (report == null) {
12028            return null;
12029        }
12030        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12031        result.setComponent(r.errorReportReceiver);
12032        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12033        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12034        return result;
12035    }
12036
12037    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12038            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12039        if (r.errorReportReceiver == null) {
12040            return null;
12041        }
12042
12043        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12044            return null;
12045        }
12046
12047        ApplicationErrorReport report = new ApplicationErrorReport();
12048        report.packageName = r.info.packageName;
12049        report.installerPackageName = r.errorReportReceiver.getPackageName();
12050        report.processName = r.processName;
12051        report.time = timeMillis;
12052        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12053
12054        if (r.crashing || r.forceCrashReport) {
12055            report.type = ApplicationErrorReport.TYPE_CRASH;
12056            report.crashInfo = crashInfo;
12057        } else if (r.notResponding) {
12058            report.type = ApplicationErrorReport.TYPE_ANR;
12059            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12060
12061            report.anrInfo.activity = r.notRespondingReport.tag;
12062            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12063            report.anrInfo.info = r.notRespondingReport.longMsg;
12064        }
12065
12066        return report;
12067    }
12068
12069    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12070        enforceNotIsolatedCaller("getProcessesInErrorState");
12071        // assume our apps are happy - lazy create the list
12072        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12073
12074        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12075                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12076        int userId = UserHandle.getUserId(Binder.getCallingUid());
12077
12078        synchronized (this) {
12079
12080            // iterate across all processes
12081            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12082                ProcessRecord app = mLruProcesses.get(i);
12083                if (!allUsers && app.userId != userId) {
12084                    continue;
12085                }
12086                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12087                    // This one's in trouble, so we'll generate a report for it
12088                    // crashes are higher priority (in case there's a crash *and* an anr)
12089                    ActivityManager.ProcessErrorStateInfo report = null;
12090                    if (app.crashing) {
12091                        report = app.crashingReport;
12092                    } else if (app.notResponding) {
12093                        report = app.notRespondingReport;
12094                    }
12095
12096                    if (report != null) {
12097                        if (errList == null) {
12098                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12099                        }
12100                        errList.add(report);
12101                    } else {
12102                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12103                                " crashing = " + app.crashing +
12104                                " notResponding = " + app.notResponding);
12105                    }
12106                }
12107            }
12108        }
12109
12110        return errList;
12111    }
12112
12113    static int procStateToImportance(int procState, int memAdj,
12114            ActivityManager.RunningAppProcessInfo currApp) {
12115        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12116        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12117            currApp.lru = memAdj;
12118        } else {
12119            currApp.lru = 0;
12120        }
12121        return imp;
12122    }
12123
12124    private void fillInProcMemInfo(ProcessRecord app,
12125            ActivityManager.RunningAppProcessInfo outInfo) {
12126        outInfo.pid = app.pid;
12127        outInfo.uid = app.info.uid;
12128        if (mHeavyWeightProcess == app) {
12129            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12130        }
12131        if (app.persistent) {
12132            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12133        }
12134        if (app.activities.size() > 0) {
12135            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12136        }
12137        outInfo.lastTrimLevel = app.trimMemoryLevel;
12138        int adj = app.curAdj;
12139        int procState = app.curProcState;
12140        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12141        outInfo.importanceReasonCode = app.adjTypeCode;
12142        outInfo.processState = app.curProcState;
12143    }
12144
12145    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12146        enforceNotIsolatedCaller("getRunningAppProcesses");
12147        // Lazy instantiation of list
12148        List<ActivityManager.RunningAppProcessInfo> runList = null;
12149        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12150                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12151        int userId = UserHandle.getUserId(Binder.getCallingUid());
12152        synchronized (this) {
12153            // Iterate across all processes
12154            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12155                ProcessRecord app = mLruProcesses.get(i);
12156                if (!allUsers && app.userId != userId) {
12157                    continue;
12158                }
12159                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12160                    // Generate process state info for running application
12161                    ActivityManager.RunningAppProcessInfo currApp =
12162                        new ActivityManager.RunningAppProcessInfo(app.processName,
12163                                app.pid, app.getPackageList());
12164                    fillInProcMemInfo(app, currApp);
12165                    if (app.adjSource instanceof ProcessRecord) {
12166                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12167                        currApp.importanceReasonImportance =
12168                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12169                                        app.adjSourceProcState);
12170                    } else if (app.adjSource instanceof ActivityRecord) {
12171                        ActivityRecord r = (ActivityRecord)app.adjSource;
12172                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12173                    }
12174                    if (app.adjTarget instanceof ComponentName) {
12175                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12176                    }
12177                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12178                    //        + " lru=" + currApp.lru);
12179                    if (runList == null) {
12180                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12181                    }
12182                    runList.add(currApp);
12183                }
12184            }
12185        }
12186        return runList;
12187    }
12188
12189    public List<ApplicationInfo> getRunningExternalApplications() {
12190        enforceNotIsolatedCaller("getRunningExternalApplications");
12191        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12192        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12193        if (runningApps != null && runningApps.size() > 0) {
12194            Set<String> extList = new HashSet<String>();
12195            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12196                if (app.pkgList != null) {
12197                    for (String pkg : app.pkgList) {
12198                        extList.add(pkg);
12199                    }
12200                }
12201            }
12202            IPackageManager pm = AppGlobals.getPackageManager();
12203            for (String pkg : extList) {
12204                try {
12205                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12206                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12207                        retList.add(info);
12208                    }
12209                } catch (RemoteException e) {
12210                }
12211            }
12212        }
12213        return retList;
12214    }
12215
12216    @Override
12217    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12218        enforceNotIsolatedCaller("getMyMemoryState");
12219        synchronized (this) {
12220            ProcessRecord proc;
12221            synchronized (mPidsSelfLocked) {
12222                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12223            }
12224            fillInProcMemInfo(proc, outInfo);
12225        }
12226    }
12227
12228    @Override
12229    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12230        if (checkCallingPermission(android.Manifest.permission.DUMP)
12231                != PackageManager.PERMISSION_GRANTED) {
12232            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12233                    + Binder.getCallingPid()
12234                    + ", uid=" + Binder.getCallingUid()
12235                    + " without permission "
12236                    + android.Manifest.permission.DUMP);
12237            return;
12238        }
12239
12240        boolean dumpAll = false;
12241        boolean dumpClient = false;
12242        String dumpPackage = null;
12243
12244        int opti = 0;
12245        while (opti < args.length) {
12246            String opt = args[opti];
12247            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12248                break;
12249            }
12250            opti++;
12251            if ("-a".equals(opt)) {
12252                dumpAll = true;
12253            } else if ("-c".equals(opt)) {
12254                dumpClient = true;
12255            } else if ("-h".equals(opt)) {
12256                pw.println("Activity manager dump options:");
12257                pw.println("  [-a] [-c] [-h] [cmd] ...");
12258                pw.println("  cmd may be one of:");
12259                pw.println("    a[ctivities]: activity stack state");
12260                pw.println("    r[recents]: recent activities state");
12261                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12262                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12263                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12264                pw.println("    o[om]: out of memory management");
12265                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12266                pw.println("    provider [COMP_SPEC]: provider client-side state");
12267                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12268                pw.println("    service [COMP_SPEC]: service client-side state");
12269                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12270                pw.println("    all: dump all activities");
12271                pw.println("    top: dump the top activity");
12272                pw.println("    write: write all pending state to storage");
12273                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12274                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12275                pw.println("    a partial substring in a component name, a");
12276                pw.println("    hex object identifier.");
12277                pw.println("  -a: include all available server state.");
12278                pw.println("  -c: include client state.");
12279                return;
12280            } else {
12281                pw.println("Unknown argument: " + opt + "; use -h for help");
12282            }
12283        }
12284
12285        long origId = Binder.clearCallingIdentity();
12286        boolean more = false;
12287        // Is the caller requesting to dump a particular piece of data?
12288        if (opti < args.length) {
12289            String cmd = args[opti];
12290            opti++;
12291            if ("activities".equals(cmd) || "a".equals(cmd)) {
12292                synchronized (this) {
12293                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12294                }
12295            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12296                synchronized (this) {
12297                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12298                }
12299            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12300                String[] newArgs;
12301                String name;
12302                if (opti >= args.length) {
12303                    name = null;
12304                    newArgs = EMPTY_STRING_ARRAY;
12305                } else {
12306                    name = args[opti];
12307                    opti++;
12308                    newArgs = new String[args.length - opti];
12309                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12310                            args.length - opti);
12311                }
12312                synchronized (this) {
12313                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12314                }
12315            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12316                String[] newArgs;
12317                String name;
12318                if (opti >= args.length) {
12319                    name = null;
12320                    newArgs = EMPTY_STRING_ARRAY;
12321                } else {
12322                    name = args[opti];
12323                    opti++;
12324                    newArgs = new String[args.length - opti];
12325                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12326                            args.length - opti);
12327                }
12328                synchronized (this) {
12329                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12330                }
12331            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12332                String[] newArgs;
12333                String name;
12334                if (opti >= args.length) {
12335                    name = null;
12336                    newArgs = EMPTY_STRING_ARRAY;
12337                } else {
12338                    name = args[opti];
12339                    opti++;
12340                    newArgs = new String[args.length - opti];
12341                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12342                            args.length - opti);
12343                }
12344                synchronized (this) {
12345                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12346                }
12347            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12348                synchronized (this) {
12349                    dumpOomLocked(fd, pw, args, opti, true);
12350                }
12351            } else if ("provider".equals(cmd)) {
12352                String[] newArgs;
12353                String name;
12354                if (opti >= args.length) {
12355                    name = null;
12356                    newArgs = EMPTY_STRING_ARRAY;
12357                } else {
12358                    name = args[opti];
12359                    opti++;
12360                    newArgs = new String[args.length - opti];
12361                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12362                }
12363                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12364                    pw.println("No providers match: " + name);
12365                    pw.println("Use -h for help.");
12366                }
12367            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12368                synchronized (this) {
12369                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12370                }
12371            } else if ("service".equals(cmd)) {
12372                String[] newArgs;
12373                String name;
12374                if (opti >= args.length) {
12375                    name = null;
12376                    newArgs = EMPTY_STRING_ARRAY;
12377                } else {
12378                    name = args[opti];
12379                    opti++;
12380                    newArgs = new String[args.length - opti];
12381                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12382                            args.length - opti);
12383                }
12384                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12385                    pw.println("No services match: " + name);
12386                    pw.println("Use -h for help.");
12387                }
12388            } else if ("package".equals(cmd)) {
12389                String[] newArgs;
12390                if (opti >= args.length) {
12391                    pw.println("package: no package name specified");
12392                    pw.println("Use -h for help.");
12393                } else {
12394                    dumpPackage = args[opti];
12395                    opti++;
12396                    newArgs = new String[args.length - opti];
12397                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12398                            args.length - opti);
12399                    args = newArgs;
12400                    opti = 0;
12401                    more = true;
12402                }
12403            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12404                synchronized (this) {
12405                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12406                }
12407            } else if ("write".equals(cmd)) {
12408                mTaskPersister.flush();
12409                pw.println("All tasks persisted.");
12410                return;
12411            } else {
12412                // Dumping a single activity?
12413                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12414                    pw.println("Bad activity command, or no activities match: " + cmd);
12415                    pw.println("Use -h for help.");
12416                }
12417            }
12418            if (!more) {
12419                Binder.restoreCallingIdentity(origId);
12420                return;
12421            }
12422        }
12423
12424        // No piece of data specified, dump everything.
12425        synchronized (this) {
12426            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12427            pw.println();
12428            if (dumpAll) {
12429                pw.println("-------------------------------------------------------------------------------");
12430            }
12431            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12432            pw.println();
12433            if (dumpAll) {
12434                pw.println("-------------------------------------------------------------------------------");
12435            }
12436            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12437            pw.println();
12438            if (dumpAll) {
12439                pw.println("-------------------------------------------------------------------------------");
12440            }
12441            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12442            pw.println();
12443            if (dumpAll) {
12444                pw.println("-------------------------------------------------------------------------------");
12445            }
12446            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12447            pw.println();
12448            if (dumpAll) {
12449                pw.println("-------------------------------------------------------------------------------");
12450            }
12451            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12452            pw.println();
12453            if (dumpAll) {
12454                pw.println("-------------------------------------------------------------------------------");
12455            }
12456            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12457        }
12458        Binder.restoreCallingIdentity(origId);
12459    }
12460
12461    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12462            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12463        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12464
12465        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12466                dumpPackage);
12467        boolean needSep = printedAnything;
12468
12469        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12470                dumpPackage, needSep, "  mFocusedActivity: ");
12471        if (printed) {
12472            printedAnything = true;
12473            needSep = false;
12474        }
12475
12476        if (dumpPackage == null) {
12477            if (needSep) {
12478                pw.println();
12479            }
12480            needSep = true;
12481            printedAnything = true;
12482            mStackSupervisor.dump(pw, "  ");
12483        }
12484
12485        if (!printedAnything) {
12486            pw.println("  (nothing)");
12487        }
12488    }
12489
12490    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12491            int opti, boolean dumpAll, String dumpPackage) {
12492        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12493
12494        boolean printedAnything = false;
12495
12496        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12497            boolean printedHeader = false;
12498
12499            final int N = mRecentTasks.size();
12500            for (int i=0; i<N; i++) {
12501                TaskRecord tr = mRecentTasks.get(i);
12502                if (dumpPackage != null) {
12503                    if (tr.realActivity == null ||
12504                            !dumpPackage.equals(tr.realActivity)) {
12505                        continue;
12506                    }
12507                }
12508                if (!printedHeader) {
12509                    pw.println("  Recent tasks:");
12510                    printedHeader = true;
12511                    printedAnything = true;
12512                }
12513                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12514                        pw.println(tr);
12515                if (dumpAll) {
12516                    mRecentTasks.get(i).dump(pw, "    ");
12517                }
12518            }
12519        }
12520
12521        if (!printedAnything) {
12522            pw.println("  (nothing)");
12523        }
12524    }
12525
12526    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12527            int opti, boolean dumpAll, String dumpPackage) {
12528        boolean needSep = false;
12529        boolean printedAnything = false;
12530        int numPers = 0;
12531
12532        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12533
12534        if (dumpAll) {
12535            final int NP = mProcessNames.getMap().size();
12536            for (int ip=0; ip<NP; ip++) {
12537                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12538                final int NA = procs.size();
12539                for (int ia=0; ia<NA; ia++) {
12540                    ProcessRecord r = procs.valueAt(ia);
12541                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12542                        continue;
12543                    }
12544                    if (!needSep) {
12545                        pw.println("  All known processes:");
12546                        needSep = true;
12547                        printedAnything = true;
12548                    }
12549                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12550                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12551                        pw.print(" "); pw.println(r);
12552                    r.dump(pw, "    ");
12553                    if (r.persistent) {
12554                        numPers++;
12555                    }
12556                }
12557            }
12558        }
12559
12560        if (mIsolatedProcesses.size() > 0) {
12561            boolean printed = false;
12562            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12563                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12564                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12565                    continue;
12566                }
12567                if (!printed) {
12568                    if (needSep) {
12569                        pw.println();
12570                    }
12571                    pw.println("  Isolated process list (sorted by uid):");
12572                    printedAnything = true;
12573                    printed = true;
12574                    needSep = true;
12575                }
12576                pw.println(String.format("%sIsolated #%2d: %s",
12577                        "    ", i, r.toString()));
12578            }
12579        }
12580
12581        if (mLruProcesses.size() > 0) {
12582            if (needSep) {
12583                pw.println();
12584            }
12585            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12586                    pw.print(" total, non-act at ");
12587                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12588                    pw.print(", non-svc at ");
12589                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12590                    pw.println("):");
12591            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12592            needSep = true;
12593            printedAnything = true;
12594        }
12595
12596        if (dumpAll || dumpPackage != null) {
12597            synchronized (mPidsSelfLocked) {
12598                boolean printed = false;
12599                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12600                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12601                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12602                        continue;
12603                    }
12604                    if (!printed) {
12605                        if (needSep) pw.println();
12606                        needSep = true;
12607                        pw.println("  PID mappings:");
12608                        printed = true;
12609                        printedAnything = true;
12610                    }
12611                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12612                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12613                }
12614            }
12615        }
12616
12617        if (mForegroundProcesses.size() > 0) {
12618            synchronized (mPidsSelfLocked) {
12619                boolean printed = false;
12620                for (int i=0; i<mForegroundProcesses.size(); i++) {
12621                    ProcessRecord r = mPidsSelfLocked.get(
12622                            mForegroundProcesses.valueAt(i).pid);
12623                    if (dumpPackage != null && (r == null
12624                            || !r.pkgList.containsKey(dumpPackage))) {
12625                        continue;
12626                    }
12627                    if (!printed) {
12628                        if (needSep) pw.println();
12629                        needSep = true;
12630                        pw.println("  Foreground Processes:");
12631                        printed = true;
12632                        printedAnything = true;
12633                    }
12634                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12635                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12636                }
12637            }
12638        }
12639
12640        if (mPersistentStartingProcesses.size() > 0) {
12641            if (needSep) pw.println();
12642            needSep = true;
12643            printedAnything = true;
12644            pw.println("  Persisent processes that are starting:");
12645            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12646                    "Starting Norm", "Restarting PERS", dumpPackage);
12647        }
12648
12649        if (mRemovedProcesses.size() > 0) {
12650            if (needSep) pw.println();
12651            needSep = true;
12652            printedAnything = true;
12653            pw.println("  Processes that are being removed:");
12654            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12655                    "Removed Norm", "Removed PERS", dumpPackage);
12656        }
12657
12658        if (mProcessesOnHold.size() > 0) {
12659            if (needSep) pw.println();
12660            needSep = true;
12661            printedAnything = true;
12662            pw.println("  Processes that are on old until the system is ready:");
12663            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12664                    "OnHold Norm", "OnHold PERS", dumpPackage);
12665        }
12666
12667        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12668
12669        if (mProcessCrashTimes.getMap().size() > 0) {
12670            boolean printed = false;
12671            long now = SystemClock.uptimeMillis();
12672            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12673            final int NP = pmap.size();
12674            for (int ip=0; ip<NP; ip++) {
12675                String pname = pmap.keyAt(ip);
12676                SparseArray<Long> uids = pmap.valueAt(ip);
12677                final int N = uids.size();
12678                for (int i=0; i<N; i++) {
12679                    int puid = uids.keyAt(i);
12680                    ProcessRecord r = mProcessNames.get(pname, puid);
12681                    if (dumpPackage != null && (r == null
12682                            || !r.pkgList.containsKey(dumpPackage))) {
12683                        continue;
12684                    }
12685                    if (!printed) {
12686                        if (needSep) pw.println();
12687                        needSep = true;
12688                        pw.println("  Time since processes crashed:");
12689                        printed = true;
12690                        printedAnything = true;
12691                    }
12692                    pw.print("    Process "); pw.print(pname);
12693                            pw.print(" uid "); pw.print(puid);
12694                            pw.print(": last crashed ");
12695                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12696                            pw.println(" ago");
12697                }
12698            }
12699        }
12700
12701        if (mBadProcesses.getMap().size() > 0) {
12702            boolean printed = false;
12703            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12704            final int NP = pmap.size();
12705            for (int ip=0; ip<NP; ip++) {
12706                String pname = pmap.keyAt(ip);
12707                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12708                final int N = uids.size();
12709                for (int i=0; i<N; i++) {
12710                    int puid = uids.keyAt(i);
12711                    ProcessRecord r = mProcessNames.get(pname, puid);
12712                    if (dumpPackage != null && (r == null
12713                            || !r.pkgList.containsKey(dumpPackage))) {
12714                        continue;
12715                    }
12716                    if (!printed) {
12717                        if (needSep) pw.println();
12718                        needSep = true;
12719                        pw.println("  Bad processes:");
12720                        printedAnything = true;
12721                    }
12722                    BadProcessInfo info = uids.valueAt(i);
12723                    pw.print("    Bad process "); pw.print(pname);
12724                            pw.print(" uid "); pw.print(puid);
12725                            pw.print(": crashed at time "); pw.println(info.time);
12726                    if (info.shortMsg != null) {
12727                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12728                    }
12729                    if (info.longMsg != null) {
12730                        pw.print("      Long msg: "); pw.println(info.longMsg);
12731                    }
12732                    if (info.stack != null) {
12733                        pw.println("      Stack:");
12734                        int lastPos = 0;
12735                        for (int pos=0; pos<info.stack.length(); pos++) {
12736                            if (info.stack.charAt(pos) == '\n') {
12737                                pw.print("        ");
12738                                pw.write(info.stack, lastPos, pos-lastPos);
12739                                pw.println();
12740                                lastPos = pos+1;
12741                            }
12742                        }
12743                        if (lastPos < info.stack.length()) {
12744                            pw.print("        ");
12745                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12746                            pw.println();
12747                        }
12748                    }
12749                }
12750            }
12751        }
12752
12753        if (dumpPackage == null) {
12754            pw.println();
12755            needSep = false;
12756            pw.println("  mStartedUsers:");
12757            for (int i=0; i<mStartedUsers.size(); i++) {
12758                UserStartedState uss = mStartedUsers.valueAt(i);
12759                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12760                        pw.print(": "); uss.dump("", pw);
12761            }
12762            pw.print("  mStartedUserArray: [");
12763            for (int i=0; i<mStartedUserArray.length; i++) {
12764                if (i > 0) pw.print(", ");
12765                pw.print(mStartedUserArray[i]);
12766            }
12767            pw.println("]");
12768            pw.print("  mUserLru: [");
12769            for (int i=0; i<mUserLru.size(); i++) {
12770                if (i > 0) pw.print(", ");
12771                pw.print(mUserLru.get(i));
12772            }
12773            pw.println("]");
12774            if (dumpAll) {
12775                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12776            }
12777            synchronized (mUserProfileGroupIdsSelfLocked) {
12778                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12779                    pw.println("  mUserProfileGroupIds:");
12780                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12781                        pw.print("    User #");
12782                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12783                        pw.print(" -> profile #");
12784                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12785                    }
12786                }
12787            }
12788        }
12789        if (mHomeProcess != null && (dumpPackage == null
12790                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12791            if (needSep) {
12792                pw.println();
12793                needSep = false;
12794            }
12795            pw.println("  mHomeProcess: " + mHomeProcess);
12796        }
12797        if (mPreviousProcess != null && (dumpPackage == null
12798                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12799            if (needSep) {
12800                pw.println();
12801                needSep = false;
12802            }
12803            pw.println("  mPreviousProcess: " + mPreviousProcess);
12804        }
12805        if (dumpAll) {
12806            StringBuilder sb = new StringBuilder(128);
12807            sb.append("  mPreviousProcessVisibleTime: ");
12808            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12809            pw.println(sb);
12810        }
12811        if (mHeavyWeightProcess != null && (dumpPackage == null
12812                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12813            if (needSep) {
12814                pw.println();
12815                needSep = false;
12816            }
12817            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12818        }
12819        if (dumpPackage == null) {
12820            pw.println("  mConfiguration: " + mConfiguration);
12821        }
12822        if (dumpAll) {
12823            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12824            if (mCompatModePackages.getPackages().size() > 0) {
12825                boolean printed = false;
12826                for (Map.Entry<String, Integer> entry
12827                        : mCompatModePackages.getPackages().entrySet()) {
12828                    String pkg = entry.getKey();
12829                    int mode = entry.getValue();
12830                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12831                        continue;
12832                    }
12833                    if (!printed) {
12834                        pw.println("  mScreenCompatPackages:");
12835                        printed = true;
12836                    }
12837                    pw.print("    "); pw.print(pkg); pw.print(": ");
12838                            pw.print(mode); pw.println();
12839                }
12840            }
12841        }
12842        if (dumpPackage == null) {
12843            pw.println("  mWakefulness="
12844                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12845            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12846                    + lockScreenShownToString());
12847            pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12848        }
12849        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12850                || mOrigWaitForDebugger) {
12851            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12852                    || dumpPackage.equals(mOrigDebugApp)) {
12853                if (needSep) {
12854                    pw.println();
12855                    needSep = false;
12856                }
12857                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12858                        + " mDebugTransient=" + mDebugTransient
12859                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12860            }
12861        }
12862        if (mOpenGlTraceApp != null) {
12863            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12864                if (needSep) {
12865                    pw.println();
12866                    needSep = false;
12867                }
12868                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12869            }
12870        }
12871        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12872                || mProfileFd != null) {
12873            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12874                if (needSep) {
12875                    pw.println();
12876                    needSep = false;
12877                }
12878                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12879                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12880                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12881                        + mAutoStopProfiler);
12882                pw.println("  mProfileType=" + mProfileType);
12883            }
12884        }
12885        if (dumpPackage == null) {
12886            if (mAlwaysFinishActivities || mController != null) {
12887                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12888                        + " mController=" + mController);
12889            }
12890            if (dumpAll) {
12891                pw.println("  Total persistent processes: " + numPers);
12892                pw.println("  mProcessesReady=" + mProcessesReady
12893                        + " mSystemReady=" + mSystemReady
12894                        + " mBooted=" + mBooted
12895                        + " mFactoryTest=" + mFactoryTest);
12896                pw.println("  mBooting=" + mBooting
12897                        + " mCallFinishBooting=" + mCallFinishBooting
12898                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12899                pw.print("  mLastPowerCheckRealtime=");
12900                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12901                        pw.println("");
12902                pw.print("  mLastPowerCheckUptime=");
12903                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12904                        pw.println("");
12905                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12906                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12907                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12908                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12909                        + " (" + mLruProcesses.size() + " total)"
12910                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12911                        + " mNumServiceProcs=" + mNumServiceProcs
12912                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12913                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12914                        + " mLastMemoryLevel" + mLastMemoryLevel
12915                        + " mLastNumProcesses" + mLastNumProcesses);
12916                long now = SystemClock.uptimeMillis();
12917                pw.print("  mLastIdleTime=");
12918                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12919                        pw.print(" mLowRamSinceLastIdle=");
12920                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12921                        pw.println();
12922            }
12923        }
12924
12925        if (!printedAnything) {
12926            pw.println("  (nothing)");
12927        }
12928    }
12929
12930    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12931            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12932        if (mProcessesToGc.size() > 0) {
12933            boolean printed = false;
12934            long now = SystemClock.uptimeMillis();
12935            for (int i=0; i<mProcessesToGc.size(); i++) {
12936                ProcessRecord proc = mProcessesToGc.get(i);
12937                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12938                    continue;
12939                }
12940                if (!printed) {
12941                    if (needSep) pw.println();
12942                    needSep = true;
12943                    pw.println("  Processes that are waiting to GC:");
12944                    printed = true;
12945                }
12946                pw.print("    Process "); pw.println(proc);
12947                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12948                        pw.print(", last gced=");
12949                        pw.print(now-proc.lastRequestedGc);
12950                        pw.print(" ms ago, last lowMem=");
12951                        pw.print(now-proc.lastLowMemory);
12952                        pw.println(" ms ago");
12953
12954            }
12955        }
12956        return needSep;
12957    }
12958
12959    void printOomLevel(PrintWriter pw, String name, int adj) {
12960        pw.print("    ");
12961        if (adj >= 0) {
12962            pw.print(' ');
12963            if (adj < 10) pw.print(' ');
12964        } else {
12965            if (adj > -10) pw.print(' ');
12966        }
12967        pw.print(adj);
12968        pw.print(": ");
12969        pw.print(name);
12970        pw.print(" (");
12971        pw.print(mProcessList.getMemLevel(adj)/1024);
12972        pw.println(" kB)");
12973    }
12974
12975    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12976            int opti, boolean dumpAll) {
12977        boolean needSep = false;
12978
12979        if (mLruProcesses.size() > 0) {
12980            if (needSep) pw.println();
12981            needSep = true;
12982            pw.println("  OOM levels:");
12983            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12984            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12985            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12986            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12987            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12988            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12989            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12990            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12991            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12992            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12993            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12994            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12995            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12996            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12997
12998            if (needSep) pw.println();
12999            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13000                    pw.print(" total, non-act at ");
13001                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13002                    pw.print(", non-svc at ");
13003                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13004                    pw.println("):");
13005            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13006            needSep = true;
13007        }
13008
13009        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13010
13011        pw.println();
13012        pw.println("  mHomeProcess: " + mHomeProcess);
13013        pw.println("  mPreviousProcess: " + mPreviousProcess);
13014        if (mHeavyWeightProcess != null) {
13015            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13016        }
13017
13018        return true;
13019    }
13020
13021    /**
13022     * There are three ways to call this:
13023     *  - no provider specified: dump all the providers
13024     *  - a flattened component name that matched an existing provider was specified as the
13025     *    first arg: dump that one provider
13026     *  - the first arg isn't the flattened component name of an existing provider:
13027     *    dump all providers whose component contains the first arg as a substring
13028     */
13029    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13030            int opti, boolean dumpAll) {
13031        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13032    }
13033
13034    static class ItemMatcher {
13035        ArrayList<ComponentName> components;
13036        ArrayList<String> strings;
13037        ArrayList<Integer> objects;
13038        boolean all;
13039
13040        ItemMatcher() {
13041            all = true;
13042        }
13043
13044        void build(String name) {
13045            ComponentName componentName = ComponentName.unflattenFromString(name);
13046            if (componentName != null) {
13047                if (components == null) {
13048                    components = new ArrayList<ComponentName>();
13049                }
13050                components.add(componentName);
13051                all = false;
13052            } else {
13053                int objectId = 0;
13054                // Not a '/' separated full component name; maybe an object ID?
13055                try {
13056                    objectId = Integer.parseInt(name, 16);
13057                    if (objects == null) {
13058                        objects = new ArrayList<Integer>();
13059                    }
13060                    objects.add(objectId);
13061                    all = false;
13062                } catch (RuntimeException e) {
13063                    // Not an integer; just do string match.
13064                    if (strings == null) {
13065                        strings = new ArrayList<String>();
13066                    }
13067                    strings.add(name);
13068                    all = false;
13069                }
13070            }
13071        }
13072
13073        int build(String[] args, int opti) {
13074            for (; opti<args.length; opti++) {
13075                String name = args[opti];
13076                if ("--".equals(name)) {
13077                    return opti+1;
13078                }
13079                build(name);
13080            }
13081            return opti;
13082        }
13083
13084        boolean match(Object object, ComponentName comp) {
13085            if (all) {
13086                return true;
13087            }
13088            if (components != null) {
13089                for (int i=0; i<components.size(); i++) {
13090                    if (components.get(i).equals(comp)) {
13091                        return true;
13092                    }
13093                }
13094            }
13095            if (objects != null) {
13096                for (int i=0; i<objects.size(); i++) {
13097                    if (System.identityHashCode(object) == objects.get(i)) {
13098                        return true;
13099                    }
13100                }
13101            }
13102            if (strings != null) {
13103                String flat = comp.flattenToString();
13104                for (int i=0; i<strings.size(); i++) {
13105                    if (flat.contains(strings.get(i))) {
13106                        return true;
13107                    }
13108                }
13109            }
13110            return false;
13111        }
13112    }
13113
13114    /**
13115     * There are three things that cmd can be:
13116     *  - a flattened component name that matches an existing activity
13117     *  - the cmd arg isn't the flattened component name of an existing activity:
13118     *    dump all activity whose component contains the cmd as a substring
13119     *  - A hex number of the ActivityRecord object instance.
13120     */
13121    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13122            int opti, boolean dumpAll) {
13123        ArrayList<ActivityRecord> activities;
13124
13125        synchronized (this) {
13126            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13127        }
13128
13129        if (activities.size() <= 0) {
13130            return false;
13131        }
13132
13133        String[] newArgs = new String[args.length - opti];
13134        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13135
13136        TaskRecord lastTask = null;
13137        boolean needSep = false;
13138        for (int i=activities.size()-1; i>=0; i--) {
13139            ActivityRecord r = activities.get(i);
13140            if (needSep) {
13141                pw.println();
13142            }
13143            needSep = true;
13144            synchronized (this) {
13145                if (lastTask != r.task) {
13146                    lastTask = r.task;
13147                    pw.print("TASK "); pw.print(lastTask.affinity);
13148                            pw.print(" id="); pw.println(lastTask.taskId);
13149                    if (dumpAll) {
13150                        lastTask.dump(pw, "  ");
13151                    }
13152                }
13153            }
13154            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13155        }
13156        return true;
13157    }
13158
13159    /**
13160     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13161     * there is a thread associated with the activity.
13162     */
13163    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13164            final ActivityRecord r, String[] args, boolean dumpAll) {
13165        String innerPrefix = prefix + "  ";
13166        synchronized (this) {
13167            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13168                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13169                    pw.print(" pid=");
13170                    if (r.app != null) pw.println(r.app.pid);
13171                    else pw.println("(not running)");
13172            if (dumpAll) {
13173                r.dump(pw, innerPrefix);
13174            }
13175        }
13176        if (r.app != null && r.app.thread != null) {
13177            // flush anything that is already in the PrintWriter since the thread is going
13178            // to write to the file descriptor directly
13179            pw.flush();
13180            try {
13181                TransferPipe tp = new TransferPipe();
13182                try {
13183                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13184                            r.appToken, innerPrefix, args);
13185                    tp.go(fd);
13186                } finally {
13187                    tp.kill();
13188                }
13189            } catch (IOException e) {
13190                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13191            } catch (RemoteException e) {
13192                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13193            }
13194        }
13195    }
13196
13197    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13198            int opti, boolean dumpAll, String dumpPackage) {
13199        boolean needSep = false;
13200        boolean onlyHistory = false;
13201        boolean printedAnything = false;
13202
13203        if ("history".equals(dumpPackage)) {
13204            if (opti < args.length && "-s".equals(args[opti])) {
13205                dumpAll = false;
13206            }
13207            onlyHistory = true;
13208            dumpPackage = null;
13209        }
13210
13211        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13212        if (!onlyHistory && dumpAll) {
13213            if (mRegisteredReceivers.size() > 0) {
13214                boolean printed = false;
13215                Iterator it = mRegisteredReceivers.values().iterator();
13216                while (it.hasNext()) {
13217                    ReceiverList r = (ReceiverList)it.next();
13218                    if (dumpPackage != null && (r.app == null ||
13219                            !dumpPackage.equals(r.app.info.packageName))) {
13220                        continue;
13221                    }
13222                    if (!printed) {
13223                        pw.println("  Registered Receivers:");
13224                        needSep = true;
13225                        printed = true;
13226                        printedAnything = true;
13227                    }
13228                    pw.print("  * "); pw.println(r);
13229                    r.dump(pw, "    ");
13230                }
13231            }
13232
13233            if (mReceiverResolver.dump(pw, needSep ?
13234                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13235                    "    ", dumpPackage, false, false)) {
13236                needSep = true;
13237                printedAnything = true;
13238            }
13239        }
13240
13241        for (BroadcastQueue q : mBroadcastQueues) {
13242            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13243            printedAnything |= needSep;
13244        }
13245
13246        needSep = true;
13247
13248        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13249            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13250                if (needSep) {
13251                    pw.println();
13252                }
13253                needSep = true;
13254                printedAnything = true;
13255                pw.print("  Sticky broadcasts for user ");
13256                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13257                StringBuilder sb = new StringBuilder(128);
13258                for (Map.Entry<String, ArrayList<Intent>> ent
13259                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13260                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13261                    if (dumpAll) {
13262                        pw.println(":");
13263                        ArrayList<Intent> intents = ent.getValue();
13264                        final int N = intents.size();
13265                        for (int i=0; i<N; i++) {
13266                            sb.setLength(0);
13267                            sb.append("    Intent: ");
13268                            intents.get(i).toShortString(sb, false, true, false, false);
13269                            pw.println(sb.toString());
13270                            Bundle bundle = intents.get(i).getExtras();
13271                            if (bundle != null) {
13272                                pw.print("      ");
13273                                pw.println(bundle.toString());
13274                            }
13275                        }
13276                    } else {
13277                        pw.println("");
13278                    }
13279                }
13280            }
13281        }
13282
13283        if (!onlyHistory && dumpAll) {
13284            pw.println();
13285            for (BroadcastQueue queue : mBroadcastQueues) {
13286                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13287                        + queue.mBroadcastsScheduled);
13288            }
13289            pw.println("  mHandler:");
13290            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13291            needSep = true;
13292            printedAnything = true;
13293        }
13294
13295        if (!printedAnything) {
13296            pw.println("  (nothing)");
13297        }
13298    }
13299
13300    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13301            int opti, boolean dumpAll, String dumpPackage) {
13302        boolean needSep;
13303        boolean printedAnything = false;
13304
13305        ItemMatcher matcher = new ItemMatcher();
13306        matcher.build(args, opti);
13307
13308        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13309
13310        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13311        printedAnything |= needSep;
13312
13313        if (mLaunchingProviders.size() > 0) {
13314            boolean printed = false;
13315            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13316                ContentProviderRecord r = mLaunchingProviders.get(i);
13317                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13318                    continue;
13319                }
13320                if (!printed) {
13321                    if (needSep) pw.println();
13322                    needSep = true;
13323                    pw.println("  Launching content providers:");
13324                    printed = true;
13325                    printedAnything = true;
13326                }
13327                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13328                        pw.println(r);
13329            }
13330        }
13331
13332        if (mGrantedUriPermissions.size() > 0) {
13333            boolean printed = false;
13334            int dumpUid = -2;
13335            if (dumpPackage != null) {
13336                try {
13337                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13338                } catch (NameNotFoundException e) {
13339                    dumpUid = -1;
13340                }
13341            }
13342            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13343                int uid = mGrantedUriPermissions.keyAt(i);
13344                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13345                    continue;
13346                }
13347                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13348                if (!printed) {
13349                    if (needSep) pw.println();
13350                    needSep = true;
13351                    pw.println("  Granted Uri Permissions:");
13352                    printed = true;
13353                    printedAnything = true;
13354                }
13355                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13356                for (UriPermission perm : perms.values()) {
13357                    pw.print("    "); pw.println(perm);
13358                    if (dumpAll) {
13359                        perm.dump(pw, "      ");
13360                    }
13361                }
13362            }
13363        }
13364
13365        if (!printedAnything) {
13366            pw.println("  (nothing)");
13367        }
13368    }
13369
13370    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13371            int opti, boolean dumpAll, String dumpPackage) {
13372        boolean printed = false;
13373
13374        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13375
13376        if (mIntentSenderRecords.size() > 0) {
13377            Iterator<WeakReference<PendingIntentRecord>> it
13378                    = mIntentSenderRecords.values().iterator();
13379            while (it.hasNext()) {
13380                WeakReference<PendingIntentRecord> ref = it.next();
13381                PendingIntentRecord rec = ref != null ? ref.get(): null;
13382                if (dumpPackage != null && (rec == null
13383                        || !dumpPackage.equals(rec.key.packageName))) {
13384                    continue;
13385                }
13386                printed = true;
13387                if (rec != null) {
13388                    pw.print("  * "); pw.println(rec);
13389                    if (dumpAll) {
13390                        rec.dump(pw, "    ");
13391                    }
13392                } else {
13393                    pw.print("  * "); pw.println(ref);
13394                }
13395            }
13396        }
13397
13398        if (!printed) {
13399            pw.println("  (nothing)");
13400        }
13401    }
13402
13403    private static final int dumpProcessList(PrintWriter pw,
13404            ActivityManagerService service, List list,
13405            String prefix, String normalLabel, String persistentLabel,
13406            String dumpPackage) {
13407        int numPers = 0;
13408        final int N = list.size()-1;
13409        for (int i=N; i>=0; i--) {
13410            ProcessRecord r = (ProcessRecord)list.get(i);
13411            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13412                continue;
13413            }
13414            pw.println(String.format("%s%s #%2d: %s",
13415                    prefix, (r.persistent ? persistentLabel : normalLabel),
13416                    i, r.toString()));
13417            if (r.persistent) {
13418                numPers++;
13419            }
13420        }
13421        return numPers;
13422    }
13423
13424    private static final boolean dumpProcessOomList(PrintWriter pw,
13425            ActivityManagerService service, List<ProcessRecord> origList,
13426            String prefix, String normalLabel, String persistentLabel,
13427            boolean inclDetails, String dumpPackage) {
13428
13429        ArrayList<Pair<ProcessRecord, Integer>> list
13430                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13431        for (int i=0; i<origList.size(); i++) {
13432            ProcessRecord r = origList.get(i);
13433            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13434                continue;
13435            }
13436            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13437        }
13438
13439        if (list.size() <= 0) {
13440            return false;
13441        }
13442
13443        Comparator<Pair<ProcessRecord, Integer>> comparator
13444                = new Comparator<Pair<ProcessRecord, Integer>>() {
13445            @Override
13446            public int compare(Pair<ProcessRecord, Integer> object1,
13447                    Pair<ProcessRecord, Integer> object2) {
13448                if (object1.first.setAdj != object2.first.setAdj) {
13449                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13450                }
13451                if (object1.second.intValue() != object2.second.intValue()) {
13452                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13453                }
13454                return 0;
13455            }
13456        };
13457
13458        Collections.sort(list, comparator);
13459
13460        final long curRealtime = SystemClock.elapsedRealtime();
13461        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13462        final long curUptime = SystemClock.uptimeMillis();
13463        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13464
13465        for (int i=list.size()-1; i>=0; i--) {
13466            ProcessRecord r = list.get(i).first;
13467            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13468            char schedGroup;
13469            switch (r.setSchedGroup) {
13470                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13471                    schedGroup = 'B';
13472                    break;
13473                case Process.THREAD_GROUP_DEFAULT:
13474                    schedGroup = 'F';
13475                    break;
13476                default:
13477                    schedGroup = '?';
13478                    break;
13479            }
13480            char foreground;
13481            if (r.foregroundActivities) {
13482                foreground = 'A';
13483            } else if (r.foregroundServices) {
13484                foreground = 'S';
13485            } else {
13486                foreground = ' ';
13487            }
13488            String procState = ProcessList.makeProcStateString(r.curProcState);
13489            pw.print(prefix);
13490            pw.print(r.persistent ? persistentLabel : normalLabel);
13491            pw.print(" #");
13492            int num = (origList.size()-1)-list.get(i).second;
13493            if (num < 10) pw.print(' ');
13494            pw.print(num);
13495            pw.print(": ");
13496            pw.print(oomAdj);
13497            pw.print(' ');
13498            pw.print(schedGroup);
13499            pw.print('/');
13500            pw.print(foreground);
13501            pw.print('/');
13502            pw.print(procState);
13503            pw.print(" trm:");
13504            if (r.trimMemoryLevel < 10) pw.print(' ');
13505            pw.print(r.trimMemoryLevel);
13506            pw.print(' ');
13507            pw.print(r.toShortString());
13508            pw.print(" (");
13509            pw.print(r.adjType);
13510            pw.println(')');
13511            if (r.adjSource != null || r.adjTarget != null) {
13512                pw.print(prefix);
13513                pw.print("    ");
13514                if (r.adjTarget instanceof ComponentName) {
13515                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13516                } else if (r.adjTarget != null) {
13517                    pw.print(r.adjTarget.toString());
13518                } else {
13519                    pw.print("{null}");
13520                }
13521                pw.print("<=");
13522                if (r.adjSource instanceof ProcessRecord) {
13523                    pw.print("Proc{");
13524                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13525                    pw.println("}");
13526                } else if (r.adjSource != null) {
13527                    pw.println(r.adjSource.toString());
13528                } else {
13529                    pw.println("{null}");
13530                }
13531            }
13532            if (inclDetails) {
13533                pw.print(prefix);
13534                pw.print("    ");
13535                pw.print("oom: max="); pw.print(r.maxAdj);
13536                pw.print(" curRaw="); pw.print(r.curRawAdj);
13537                pw.print(" setRaw="); pw.print(r.setRawAdj);
13538                pw.print(" cur="); pw.print(r.curAdj);
13539                pw.print(" set="); pw.println(r.setAdj);
13540                pw.print(prefix);
13541                pw.print("    ");
13542                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13543                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13544                pw.print(" lastPss="); pw.print(r.lastPss);
13545                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13546                pw.print(prefix);
13547                pw.print("    ");
13548                pw.print("cached="); pw.print(r.cached);
13549                pw.print(" empty="); pw.print(r.empty);
13550                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13551
13552                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13553                    if (r.lastWakeTime != 0) {
13554                        long wtime;
13555                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13556                        synchronized (stats) {
13557                            wtime = stats.getProcessWakeTime(r.info.uid,
13558                                    r.pid, curRealtime);
13559                        }
13560                        long timeUsed = wtime - r.lastWakeTime;
13561                        pw.print(prefix);
13562                        pw.print("    ");
13563                        pw.print("keep awake over ");
13564                        TimeUtils.formatDuration(realtimeSince, pw);
13565                        pw.print(" used ");
13566                        TimeUtils.formatDuration(timeUsed, pw);
13567                        pw.print(" (");
13568                        pw.print((timeUsed*100)/realtimeSince);
13569                        pw.println("%)");
13570                    }
13571                    if (r.lastCpuTime != 0) {
13572                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13573                        pw.print(prefix);
13574                        pw.print("    ");
13575                        pw.print("run cpu over ");
13576                        TimeUtils.formatDuration(uptimeSince, pw);
13577                        pw.print(" used ");
13578                        TimeUtils.formatDuration(timeUsed, pw);
13579                        pw.print(" (");
13580                        pw.print((timeUsed*100)/uptimeSince);
13581                        pw.println("%)");
13582                    }
13583                }
13584            }
13585        }
13586        return true;
13587    }
13588
13589    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13590            String[] args) {
13591        ArrayList<ProcessRecord> procs;
13592        synchronized (this) {
13593            if (args != null && args.length > start
13594                    && args[start].charAt(0) != '-') {
13595                procs = new ArrayList<ProcessRecord>();
13596                int pid = -1;
13597                try {
13598                    pid = Integer.parseInt(args[start]);
13599                } catch (NumberFormatException e) {
13600                }
13601                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13602                    ProcessRecord proc = mLruProcesses.get(i);
13603                    if (proc.pid == pid) {
13604                        procs.add(proc);
13605                    } else if (allPkgs && proc.pkgList != null
13606                            && proc.pkgList.containsKey(args[start])) {
13607                        procs.add(proc);
13608                    } else if (proc.processName.equals(args[start])) {
13609                        procs.add(proc);
13610                    }
13611                }
13612                if (procs.size() <= 0) {
13613                    return null;
13614                }
13615            } else {
13616                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13617            }
13618        }
13619        return procs;
13620    }
13621
13622    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13623            PrintWriter pw, String[] args) {
13624        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13625        if (procs == null) {
13626            pw.println("No process found for: " + args[0]);
13627            return;
13628        }
13629
13630        long uptime = SystemClock.uptimeMillis();
13631        long realtime = SystemClock.elapsedRealtime();
13632        pw.println("Applications Graphics Acceleration Info:");
13633        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13634
13635        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13636            ProcessRecord r = procs.get(i);
13637            if (r.thread != null) {
13638                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13639                pw.flush();
13640                try {
13641                    TransferPipe tp = new TransferPipe();
13642                    try {
13643                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13644                        tp.go(fd);
13645                    } finally {
13646                        tp.kill();
13647                    }
13648                } catch (IOException e) {
13649                    pw.println("Failure while dumping the app: " + r);
13650                    pw.flush();
13651                } catch (RemoteException e) {
13652                    pw.println("Got a RemoteException while dumping the app " + r);
13653                    pw.flush();
13654                }
13655            }
13656        }
13657    }
13658
13659    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13660        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13661        if (procs == null) {
13662            pw.println("No process found for: " + args[0]);
13663            return;
13664        }
13665
13666        pw.println("Applications Database Info:");
13667
13668        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13669            ProcessRecord r = procs.get(i);
13670            if (r.thread != null) {
13671                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13672                pw.flush();
13673                try {
13674                    TransferPipe tp = new TransferPipe();
13675                    try {
13676                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13677                        tp.go(fd);
13678                    } finally {
13679                        tp.kill();
13680                    }
13681                } catch (IOException e) {
13682                    pw.println("Failure while dumping the app: " + r);
13683                    pw.flush();
13684                } catch (RemoteException e) {
13685                    pw.println("Got a RemoteException while dumping the app " + r);
13686                    pw.flush();
13687                }
13688            }
13689        }
13690    }
13691
13692    final static class MemItem {
13693        final boolean isProc;
13694        final String label;
13695        final String shortLabel;
13696        final long pss;
13697        final int id;
13698        final boolean hasActivities;
13699        ArrayList<MemItem> subitems;
13700
13701        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13702                boolean _hasActivities) {
13703            isProc = true;
13704            label = _label;
13705            shortLabel = _shortLabel;
13706            pss = _pss;
13707            id = _id;
13708            hasActivities = _hasActivities;
13709        }
13710
13711        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13712            isProc = false;
13713            label = _label;
13714            shortLabel = _shortLabel;
13715            pss = _pss;
13716            id = _id;
13717            hasActivities = false;
13718        }
13719    }
13720
13721    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13722            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13723        if (sort && !isCompact) {
13724            Collections.sort(items, new Comparator<MemItem>() {
13725                @Override
13726                public int compare(MemItem lhs, MemItem rhs) {
13727                    if (lhs.pss < rhs.pss) {
13728                        return 1;
13729                    } else if (lhs.pss > rhs.pss) {
13730                        return -1;
13731                    }
13732                    return 0;
13733                }
13734            });
13735        }
13736
13737        for (int i=0; i<items.size(); i++) {
13738            MemItem mi = items.get(i);
13739            if (!isCompact) {
13740                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13741            } else if (mi.isProc) {
13742                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13743                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13744                pw.println(mi.hasActivities ? ",a" : ",e");
13745            } else {
13746                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13747                pw.println(mi.pss);
13748            }
13749            if (mi.subitems != null) {
13750                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13751                        true, isCompact);
13752            }
13753        }
13754    }
13755
13756    // These are in KB.
13757    static final long[] DUMP_MEM_BUCKETS = new long[] {
13758        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13759        120*1024, 160*1024, 200*1024,
13760        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13761        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13762    };
13763
13764    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13765            boolean stackLike) {
13766        int start = label.lastIndexOf('.');
13767        if (start >= 0) start++;
13768        else start = 0;
13769        int end = label.length();
13770        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13771            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13772                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13773                out.append(bucket);
13774                out.append(stackLike ? "MB." : "MB ");
13775                out.append(label, start, end);
13776                return;
13777            }
13778        }
13779        out.append(memKB/1024);
13780        out.append(stackLike ? "MB." : "MB ");
13781        out.append(label, start, end);
13782    }
13783
13784    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13785            ProcessList.NATIVE_ADJ,
13786            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13787            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13788            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13789            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13790            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13791            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13792    };
13793    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13794            "Native",
13795            "System", "Persistent", "Persistent Service", "Foreground",
13796            "Visible", "Perceptible",
13797            "Heavy Weight", "Backup",
13798            "A Services", "Home",
13799            "Previous", "B Services", "Cached"
13800    };
13801    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13802            "native",
13803            "sys", "pers", "persvc", "fore",
13804            "vis", "percept",
13805            "heavy", "backup",
13806            "servicea", "home",
13807            "prev", "serviceb", "cached"
13808    };
13809
13810    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13811            long realtime, boolean isCheckinRequest, boolean isCompact) {
13812        if (isCheckinRequest || isCompact) {
13813            // short checkin version
13814            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13815        } else {
13816            pw.println("Applications Memory Usage (kB):");
13817            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13818        }
13819    }
13820
13821    private static final int KSM_SHARED = 0;
13822    private static final int KSM_SHARING = 1;
13823    private static final int KSM_UNSHARED = 2;
13824    private static final int KSM_VOLATILE = 3;
13825
13826    private final long[] getKsmInfo() {
13827        long[] longOut = new long[4];
13828        final int[] SINGLE_LONG_FORMAT = new int[] {
13829            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13830        };
13831        long[] longTmp = new long[1];
13832        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13833                SINGLE_LONG_FORMAT, null, longTmp, null);
13834        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13835        longTmp[0] = 0;
13836        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13837                SINGLE_LONG_FORMAT, null, longTmp, null);
13838        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13839        longTmp[0] = 0;
13840        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13841                SINGLE_LONG_FORMAT, null, longTmp, null);
13842        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13843        longTmp[0] = 0;
13844        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13845                SINGLE_LONG_FORMAT, null, longTmp, null);
13846        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13847        return longOut;
13848    }
13849
13850    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13851            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13852        boolean dumpDetails = false;
13853        boolean dumpFullDetails = false;
13854        boolean dumpDalvik = false;
13855        boolean oomOnly = false;
13856        boolean isCompact = false;
13857        boolean localOnly = false;
13858        boolean packages = false;
13859
13860        int opti = 0;
13861        while (opti < args.length) {
13862            String opt = args[opti];
13863            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13864                break;
13865            }
13866            opti++;
13867            if ("-a".equals(opt)) {
13868                dumpDetails = true;
13869                dumpFullDetails = true;
13870                dumpDalvik = true;
13871            } else if ("-d".equals(opt)) {
13872                dumpDalvik = true;
13873            } else if ("-c".equals(opt)) {
13874                isCompact = true;
13875            } else if ("--oom".equals(opt)) {
13876                oomOnly = true;
13877            } else if ("--local".equals(opt)) {
13878                localOnly = true;
13879            } else if ("--package".equals(opt)) {
13880                packages = true;
13881            } else if ("-h".equals(opt)) {
13882                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13883                pw.println("  -a: include all available information for each process.");
13884                pw.println("  -d: include dalvik details when dumping process details.");
13885                pw.println("  -c: dump in a compact machine-parseable representation.");
13886                pw.println("  --oom: only show processes organized by oom adj.");
13887                pw.println("  --local: only collect details locally, don't call process.");
13888                pw.println("  --package: interpret process arg as package, dumping all");
13889                pw.println("             processes that have loaded that package.");
13890                pw.println("If [process] is specified it can be the name or ");
13891                pw.println("pid of a specific process to dump.");
13892                return;
13893            } else {
13894                pw.println("Unknown argument: " + opt + "; use -h for help");
13895            }
13896        }
13897
13898        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13899        long uptime = SystemClock.uptimeMillis();
13900        long realtime = SystemClock.elapsedRealtime();
13901        final long[] tmpLong = new long[1];
13902
13903        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13904        if (procs == null) {
13905            // No Java processes.  Maybe they want to print a native process.
13906            if (args != null && args.length > opti
13907                    && args[opti].charAt(0) != '-') {
13908                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13909                        = new ArrayList<ProcessCpuTracker.Stats>();
13910                updateCpuStatsNow();
13911                int findPid = -1;
13912                try {
13913                    findPid = Integer.parseInt(args[opti]);
13914                } catch (NumberFormatException e) {
13915                }
13916                synchronized (mProcessCpuTracker) {
13917                    final int N = mProcessCpuTracker.countStats();
13918                    for (int i=0; i<N; i++) {
13919                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13920                        if (st.pid == findPid || (st.baseName != null
13921                                && st.baseName.equals(args[opti]))) {
13922                            nativeProcs.add(st);
13923                        }
13924                    }
13925                }
13926                if (nativeProcs.size() > 0) {
13927                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13928                            isCompact);
13929                    Debug.MemoryInfo mi = null;
13930                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13931                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13932                        final int pid = r.pid;
13933                        if (!isCheckinRequest && dumpDetails) {
13934                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13935                        }
13936                        if (mi == null) {
13937                            mi = new Debug.MemoryInfo();
13938                        }
13939                        if (dumpDetails || (!brief && !oomOnly)) {
13940                            Debug.getMemoryInfo(pid, mi);
13941                        } else {
13942                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13943                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13944                        }
13945                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13946                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13947                        if (isCheckinRequest) {
13948                            pw.println();
13949                        }
13950                    }
13951                    return;
13952                }
13953            }
13954            pw.println("No process found for: " + args[opti]);
13955            return;
13956        }
13957
13958        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13959            dumpDetails = true;
13960        }
13961
13962        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13963
13964        String[] innerArgs = new String[args.length-opti];
13965        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13966
13967        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13968        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13969        long nativePss = 0;
13970        long dalvikPss = 0;
13971        long otherPss = 0;
13972        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13973
13974        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13975        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13976                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13977
13978        long totalPss = 0;
13979        long cachedPss = 0;
13980
13981        Debug.MemoryInfo mi = null;
13982        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13983            final ProcessRecord r = procs.get(i);
13984            final IApplicationThread thread;
13985            final int pid;
13986            final int oomAdj;
13987            final boolean hasActivities;
13988            synchronized (this) {
13989                thread = r.thread;
13990                pid = r.pid;
13991                oomAdj = r.getSetAdjWithServices();
13992                hasActivities = r.activities.size() > 0;
13993            }
13994            if (thread != null) {
13995                if (!isCheckinRequest && dumpDetails) {
13996                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13997                }
13998                if (mi == null) {
13999                    mi = new Debug.MemoryInfo();
14000                }
14001                if (dumpDetails || (!brief && !oomOnly)) {
14002                    Debug.getMemoryInfo(pid, mi);
14003                } else {
14004                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14005                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14006                }
14007                if (dumpDetails) {
14008                    if (localOnly) {
14009                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14010                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14011                        if (isCheckinRequest) {
14012                            pw.println();
14013                        }
14014                    } else {
14015                        try {
14016                            pw.flush();
14017                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14018                                    dumpDalvik, innerArgs);
14019                        } catch (RemoteException e) {
14020                            if (!isCheckinRequest) {
14021                                pw.println("Got RemoteException!");
14022                                pw.flush();
14023                            }
14024                        }
14025                    }
14026                }
14027
14028                final long myTotalPss = mi.getTotalPss();
14029                final long myTotalUss = mi.getTotalUss();
14030
14031                synchronized (this) {
14032                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14033                        // Record this for posterity if the process has been stable.
14034                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14035                    }
14036                }
14037
14038                if (!isCheckinRequest && mi != null) {
14039                    totalPss += myTotalPss;
14040                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14041                            (hasActivities ? " / activities)" : ")"),
14042                            r.processName, myTotalPss, pid, hasActivities);
14043                    procMems.add(pssItem);
14044                    procMemsMap.put(pid, pssItem);
14045
14046                    nativePss += mi.nativePss;
14047                    dalvikPss += mi.dalvikPss;
14048                    otherPss += mi.otherPss;
14049                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14050                        long mem = mi.getOtherPss(j);
14051                        miscPss[j] += mem;
14052                        otherPss -= mem;
14053                    }
14054
14055                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14056                        cachedPss += myTotalPss;
14057                    }
14058
14059                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14060                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14061                                || oomIndex == (oomPss.length-1)) {
14062                            oomPss[oomIndex] += myTotalPss;
14063                            if (oomProcs[oomIndex] == null) {
14064                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14065                            }
14066                            oomProcs[oomIndex].add(pssItem);
14067                            break;
14068                        }
14069                    }
14070                }
14071            }
14072        }
14073
14074        long nativeProcTotalPss = 0;
14075
14076        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14077            // If we are showing aggregations, also look for native processes to
14078            // include so that our aggregations are more accurate.
14079            updateCpuStatsNow();
14080            synchronized (mProcessCpuTracker) {
14081                final int N = mProcessCpuTracker.countStats();
14082                for (int i=0; i<N; i++) {
14083                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14084                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14085                        if (mi == null) {
14086                            mi = new Debug.MemoryInfo();
14087                        }
14088                        if (!brief && !oomOnly) {
14089                            Debug.getMemoryInfo(st.pid, mi);
14090                        } else {
14091                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14092                            mi.nativePrivateDirty = (int)tmpLong[0];
14093                        }
14094
14095                        final long myTotalPss = mi.getTotalPss();
14096                        totalPss += myTotalPss;
14097                        nativeProcTotalPss += myTotalPss;
14098
14099                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14100                                st.name, myTotalPss, st.pid, false);
14101                        procMems.add(pssItem);
14102
14103                        nativePss += mi.nativePss;
14104                        dalvikPss += mi.dalvikPss;
14105                        otherPss += mi.otherPss;
14106                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14107                            long mem = mi.getOtherPss(j);
14108                            miscPss[j] += mem;
14109                            otherPss -= mem;
14110                        }
14111                        oomPss[0] += myTotalPss;
14112                        if (oomProcs[0] == null) {
14113                            oomProcs[0] = new ArrayList<MemItem>();
14114                        }
14115                        oomProcs[0].add(pssItem);
14116                    }
14117                }
14118            }
14119
14120            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14121
14122            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14123            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14124            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14125            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14126                String label = Debug.MemoryInfo.getOtherLabel(j);
14127                catMems.add(new MemItem(label, label, miscPss[j], j));
14128            }
14129
14130            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14131            for (int j=0; j<oomPss.length; j++) {
14132                if (oomPss[j] != 0) {
14133                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14134                            : DUMP_MEM_OOM_LABEL[j];
14135                    MemItem item = new MemItem(label, label, oomPss[j],
14136                            DUMP_MEM_OOM_ADJ[j]);
14137                    item.subitems = oomProcs[j];
14138                    oomMems.add(item);
14139                }
14140            }
14141
14142            if (!brief && !oomOnly && !isCompact) {
14143                pw.println();
14144                pw.println("Total PSS by process:");
14145                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14146                pw.println();
14147            }
14148            if (!isCompact) {
14149                pw.println("Total PSS by OOM adjustment:");
14150            }
14151            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14152            if (!brief && !oomOnly) {
14153                PrintWriter out = categoryPw != null ? categoryPw : pw;
14154                if (!isCompact) {
14155                    out.println();
14156                    out.println("Total PSS by category:");
14157                }
14158                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14159            }
14160            if (!isCompact) {
14161                pw.println();
14162            }
14163            MemInfoReader memInfo = new MemInfoReader();
14164            memInfo.readMemInfo();
14165            if (nativeProcTotalPss > 0) {
14166                synchronized (this) {
14167                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14168                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14169                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14170                }
14171            }
14172            if (!brief) {
14173                if (!isCompact) {
14174                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14175                    pw.print(" kB (status ");
14176                    switch (mLastMemoryLevel) {
14177                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14178                            pw.println("normal)");
14179                            break;
14180                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14181                            pw.println("moderate)");
14182                            break;
14183                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14184                            pw.println("low)");
14185                            break;
14186                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14187                            pw.println("critical)");
14188                            break;
14189                        default:
14190                            pw.print(mLastMemoryLevel);
14191                            pw.println(")");
14192                            break;
14193                    }
14194                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14195                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14196                            pw.print(cachedPss); pw.print(" cached pss + ");
14197                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14198                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14199                } else {
14200                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14201                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14202                            + memInfo.getFreeSizeKb()); pw.print(",");
14203                    pw.println(totalPss - cachedPss);
14204                }
14205            }
14206            if (!isCompact) {
14207                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14208                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14209                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14210                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14211                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14212                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14213                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14214            }
14215            if (!brief) {
14216                if (memInfo.getZramTotalSizeKb() != 0) {
14217                    if (!isCompact) {
14218                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14219                                pw.print(" kB physical used for ");
14220                                pw.print(memInfo.getSwapTotalSizeKb()
14221                                        - memInfo.getSwapFreeSizeKb());
14222                                pw.print(" kB in swap (");
14223                                pw.print(memInfo.getSwapTotalSizeKb());
14224                                pw.println(" kB total swap)");
14225                    } else {
14226                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14227                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14228                                pw.println(memInfo.getSwapFreeSizeKb());
14229                    }
14230                }
14231                final long[] ksm = getKsmInfo();
14232                if (!isCompact) {
14233                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14234                            || ksm[KSM_VOLATILE] != 0) {
14235                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14236                                pw.print(" kB saved from shared ");
14237                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14238                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14239                                pw.print(" kB unshared; ");
14240                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14241                    }
14242                    pw.print("   Tuning: ");
14243                    pw.print(ActivityManager.staticGetMemoryClass());
14244                    pw.print(" (large ");
14245                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14246                    pw.print("), oom ");
14247                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14248                    pw.print(" kB");
14249                    pw.print(", restore limit ");
14250                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14251                    pw.print(" kB");
14252                    if (ActivityManager.isLowRamDeviceStatic()) {
14253                        pw.print(" (low-ram)");
14254                    }
14255                    if (ActivityManager.isHighEndGfx()) {
14256                        pw.print(" (high-end-gfx)");
14257                    }
14258                    pw.println();
14259                } else {
14260                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14261                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14262                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14263                    pw.print("tuning,");
14264                    pw.print(ActivityManager.staticGetMemoryClass());
14265                    pw.print(',');
14266                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14267                    pw.print(',');
14268                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14269                    if (ActivityManager.isLowRamDeviceStatic()) {
14270                        pw.print(",low-ram");
14271                    }
14272                    if (ActivityManager.isHighEndGfx()) {
14273                        pw.print(",high-end-gfx");
14274                    }
14275                    pw.println();
14276                }
14277            }
14278        }
14279    }
14280
14281    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14282            String name) {
14283        sb.append("  ");
14284        sb.append(ProcessList.makeOomAdjString(oomAdj));
14285        sb.append(' ');
14286        sb.append(ProcessList.makeProcStateString(procState));
14287        sb.append(' ');
14288        ProcessList.appendRamKb(sb, pss);
14289        sb.append(" kB: ");
14290        sb.append(name);
14291    }
14292
14293    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14294        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14295        sb.append(" (");
14296        sb.append(mi.pid);
14297        sb.append(") ");
14298        sb.append(mi.adjType);
14299        sb.append('\n');
14300        if (mi.adjReason != null) {
14301            sb.append("                      ");
14302            sb.append(mi.adjReason);
14303            sb.append('\n');
14304        }
14305    }
14306
14307    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14308        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14309        for (int i=0, N=memInfos.size(); i<N; i++) {
14310            ProcessMemInfo mi = memInfos.get(i);
14311            infoMap.put(mi.pid, mi);
14312        }
14313        updateCpuStatsNow();
14314        synchronized (mProcessCpuTracker) {
14315            final int N = mProcessCpuTracker.countStats();
14316            for (int i=0; i<N; i++) {
14317                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14318                if (st.vsize > 0) {
14319                    long pss = Debug.getPss(st.pid, null);
14320                    if (pss > 0) {
14321                        if (infoMap.indexOfKey(st.pid) < 0) {
14322                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14323                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14324                            mi.pss = pss;
14325                            memInfos.add(mi);
14326                        }
14327                    }
14328                }
14329            }
14330        }
14331
14332        long totalPss = 0;
14333        for (int i=0, N=memInfos.size(); i<N; i++) {
14334            ProcessMemInfo mi = memInfos.get(i);
14335            if (mi.pss == 0) {
14336                mi.pss = Debug.getPss(mi.pid, null);
14337            }
14338            totalPss += mi.pss;
14339        }
14340        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14341            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14342                if (lhs.oomAdj != rhs.oomAdj) {
14343                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14344                }
14345                if (lhs.pss != rhs.pss) {
14346                    return lhs.pss < rhs.pss ? 1 : -1;
14347                }
14348                return 0;
14349            }
14350        });
14351
14352        StringBuilder tag = new StringBuilder(128);
14353        StringBuilder stack = new StringBuilder(128);
14354        tag.append("Low on memory -- ");
14355        appendMemBucket(tag, totalPss, "total", false);
14356        appendMemBucket(stack, totalPss, "total", true);
14357
14358        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14359        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14360        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14361
14362        boolean firstLine = true;
14363        int lastOomAdj = Integer.MIN_VALUE;
14364        long extraNativeRam = 0;
14365        long cachedPss = 0;
14366        for (int i=0, N=memInfos.size(); i<N; i++) {
14367            ProcessMemInfo mi = memInfos.get(i);
14368
14369            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14370                cachedPss += mi.pss;
14371            }
14372
14373            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14374                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14375                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14376                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14377                if (lastOomAdj != mi.oomAdj) {
14378                    lastOomAdj = mi.oomAdj;
14379                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14380                        tag.append(" / ");
14381                    }
14382                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14383                        if (firstLine) {
14384                            stack.append(":");
14385                            firstLine = false;
14386                        }
14387                        stack.append("\n\t at ");
14388                    } else {
14389                        stack.append("$");
14390                    }
14391                } else {
14392                    tag.append(" ");
14393                    stack.append("$");
14394                }
14395                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14396                    appendMemBucket(tag, mi.pss, mi.name, false);
14397                }
14398                appendMemBucket(stack, mi.pss, mi.name, true);
14399                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14400                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14401                    stack.append("(");
14402                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14403                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14404                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14405                            stack.append(":");
14406                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14407                        }
14408                    }
14409                    stack.append(")");
14410                }
14411            }
14412
14413            appendMemInfo(fullNativeBuilder, mi);
14414            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14415                // The short form only has native processes that are >= 1MB.
14416                if (mi.pss >= 1000) {
14417                    appendMemInfo(shortNativeBuilder, mi);
14418                } else {
14419                    extraNativeRam += mi.pss;
14420                }
14421            } else {
14422                // Short form has all other details, but if we have collected RAM
14423                // from smaller native processes let's dump a summary of that.
14424                if (extraNativeRam > 0) {
14425                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14426                            -1, extraNativeRam, "(Other native)");
14427                    shortNativeBuilder.append('\n');
14428                    extraNativeRam = 0;
14429                }
14430                appendMemInfo(fullJavaBuilder, mi);
14431            }
14432        }
14433
14434        fullJavaBuilder.append("           ");
14435        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14436        fullJavaBuilder.append(" kB: TOTAL\n");
14437
14438        MemInfoReader memInfo = new MemInfoReader();
14439        memInfo.readMemInfo();
14440        final long[] infos = memInfo.getRawInfo();
14441
14442        StringBuilder memInfoBuilder = new StringBuilder(1024);
14443        Debug.getMemInfo(infos);
14444        memInfoBuilder.append("  MemInfo: ");
14445        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14446        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14447        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14448        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14449        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14450        memInfoBuilder.append("           ");
14451        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14452        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14453        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14454        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14455        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14456            memInfoBuilder.append("  ZRAM: ");
14457            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14458            memInfoBuilder.append(" kB RAM, ");
14459            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14460            memInfoBuilder.append(" kB swap total, ");
14461            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14462            memInfoBuilder.append(" kB swap free\n");
14463        }
14464        final long[] ksm = getKsmInfo();
14465        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14466                || ksm[KSM_VOLATILE] != 0) {
14467            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14468            memInfoBuilder.append(" kB saved from shared ");
14469            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14470            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14471            memInfoBuilder.append(" kB unshared; ");
14472            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14473        }
14474        memInfoBuilder.append("  Free RAM: ");
14475        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14476                + memInfo.getFreeSizeKb());
14477        memInfoBuilder.append(" kB\n");
14478        memInfoBuilder.append("  Used RAM: ");
14479        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14480        memInfoBuilder.append(" kB\n");
14481        memInfoBuilder.append("  Lost RAM: ");
14482        memInfoBuilder.append(memInfo.getTotalSizeKb()
14483                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14484                - memInfo.getKernelUsedSizeKb());
14485        memInfoBuilder.append(" kB\n");
14486        Slog.i(TAG, "Low on memory:");
14487        Slog.i(TAG, shortNativeBuilder.toString());
14488        Slog.i(TAG, fullJavaBuilder.toString());
14489        Slog.i(TAG, memInfoBuilder.toString());
14490
14491        StringBuilder dropBuilder = new StringBuilder(1024);
14492        /*
14493        StringWriter oomSw = new StringWriter();
14494        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14495        StringWriter catSw = new StringWriter();
14496        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14497        String[] emptyArgs = new String[] { };
14498        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14499        oomPw.flush();
14500        String oomString = oomSw.toString();
14501        */
14502        dropBuilder.append("Low on memory:");
14503        dropBuilder.append(stack);
14504        dropBuilder.append('\n');
14505        dropBuilder.append(fullNativeBuilder);
14506        dropBuilder.append(fullJavaBuilder);
14507        dropBuilder.append('\n');
14508        dropBuilder.append(memInfoBuilder);
14509        dropBuilder.append('\n');
14510        /*
14511        dropBuilder.append(oomString);
14512        dropBuilder.append('\n');
14513        */
14514        StringWriter catSw = new StringWriter();
14515        synchronized (ActivityManagerService.this) {
14516            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14517            String[] emptyArgs = new String[] { };
14518            catPw.println();
14519            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14520            catPw.println();
14521            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14522                    false, false, null);
14523            catPw.println();
14524            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14525            catPw.flush();
14526        }
14527        dropBuilder.append(catSw.toString());
14528        addErrorToDropBox("lowmem", null, "system_server", null,
14529                null, tag.toString(), dropBuilder.toString(), null, null);
14530        //Slog.i(TAG, "Sent to dropbox:");
14531        //Slog.i(TAG, dropBuilder.toString());
14532        synchronized (ActivityManagerService.this) {
14533            long now = SystemClock.uptimeMillis();
14534            if (mLastMemUsageReportTime < now) {
14535                mLastMemUsageReportTime = now;
14536            }
14537        }
14538    }
14539
14540    /**
14541     * Searches array of arguments for the specified string
14542     * @param args array of argument strings
14543     * @param value value to search for
14544     * @return true if the value is contained in the array
14545     */
14546    private static boolean scanArgs(String[] args, String value) {
14547        if (args != null) {
14548            for (String arg : args) {
14549                if (value.equals(arg)) {
14550                    return true;
14551                }
14552            }
14553        }
14554        return false;
14555    }
14556
14557    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14558            ContentProviderRecord cpr, boolean always) {
14559        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14560
14561        if (!inLaunching || always) {
14562            synchronized (cpr) {
14563                cpr.launchingApp = null;
14564                cpr.notifyAll();
14565            }
14566            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14567            String names[] = cpr.info.authority.split(";");
14568            for (int j = 0; j < names.length; j++) {
14569                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14570            }
14571        }
14572
14573        for (int i=0; i<cpr.connections.size(); i++) {
14574            ContentProviderConnection conn = cpr.connections.get(i);
14575            if (conn.waiting) {
14576                // If this connection is waiting for the provider, then we don't
14577                // need to mess with its process unless we are always removing
14578                // or for some reason the provider is not currently launching.
14579                if (inLaunching && !always) {
14580                    continue;
14581                }
14582            }
14583            ProcessRecord capp = conn.client;
14584            conn.dead = true;
14585            if (conn.stableCount > 0) {
14586                if (!capp.persistent && capp.thread != null
14587                        && capp.pid != 0
14588                        && capp.pid != MY_PID) {
14589                    capp.kill("depends on provider "
14590                            + cpr.name.flattenToShortString()
14591                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14592                }
14593            } else if (capp.thread != null && conn.provider.provider != null) {
14594                try {
14595                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14596                } catch (RemoteException e) {
14597                }
14598                // In the protocol here, we don't expect the client to correctly
14599                // clean up this connection, we'll just remove it.
14600                cpr.connections.remove(i);
14601                conn.client.conProviders.remove(conn);
14602            }
14603        }
14604
14605        if (inLaunching && always) {
14606            mLaunchingProviders.remove(cpr);
14607        }
14608        return inLaunching;
14609    }
14610
14611    /**
14612     * Main code for cleaning up a process when it has gone away.  This is
14613     * called both as a result of the process dying, or directly when stopping
14614     * a process when running in single process mode.
14615     *
14616     * @return Returns true if the given process has been restarted, so the
14617     * app that was passed in must remain on the process lists.
14618     */
14619    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14620            boolean restarting, boolean allowRestart, int index) {
14621        if (index >= 0) {
14622            removeLruProcessLocked(app);
14623            ProcessList.remove(app.pid);
14624        }
14625
14626        mProcessesToGc.remove(app);
14627        mPendingPssProcesses.remove(app);
14628
14629        // Dismiss any open dialogs.
14630        if (app.crashDialog != null && !app.forceCrashReport) {
14631            app.crashDialog.dismiss();
14632            app.crashDialog = null;
14633        }
14634        if (app.anrDialog != null) {
14635            app.anrDialog.dismiss();
14636            app.anrDialog = null;
14637        }
14638        if (app.waitDialog != null) {
14639            app.waitDialog.dismiss();
14640            app.waitDialog = null;
14641        }
14642
14643        app.crashing = false;
14644        app.notResponding = false;
14645
14646        app.resetPackageList(mProcessStats);
14647        app.unlinkDeathRecipient();
14648        app.makeInactive(mProcessStats);
14649        app.waitingToKill = null;
14650        app.forcingToForeground = null;
14651        updateProcessForegroundLocked(app, false, false);
14652        app.foregroundActivities = false;
14653        app.hasShownUi = false;
14654        app.treatLikeActivity = false;
14655        app.hasAboveClient = false;
14656        app.hasClientActivities = false;
14657
14658        mServices.killServicesLocked(app, allowRestart);
14659
14660        boolean restart = false;
14661
14662        // Remove published content providers.
14663        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14664            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14665            final boolean always = app.bad || !allowRestart;
14666            if (removeDyingProviderLocked(app, cpr, always) || always) {
14667                // We left the provider in the launching list, need to
14668                // restart it.
14669                restart = true;
14670            }
14671
14672            cpr.provider = null;
14673            cpr.proc = null;
14674        }
14675        app.pubProviders.clear();
14676
14677        // Take care of any launching providers waiting for this process.
14678        if (checkAppInLaunchingProvidersLocked(app, false)) {
14679            restart = true;
14680        }
14681
14682        // Unregister from connected content providers.
14683        if (!app.conProviders.isEmpty()) {
14684            for (int i=0; i<app.conProviders.size(); i++) {
14685                ContentProviderConnection conn = app.conProviders.get(i);
14686                conn.provider.connections.remove(conn);
14687            }
14688            app.conProviders.clear();
14689        }
14690
14691        // At this point there may be remaining entries in mLaunchingProviders
14692        // where we were the only one waiting, so they are no longer of use.
14693        // Look for these and clean up if found.
14694        // XXX Commented out for now.  Trying to figure out a way to reproduce
14695        // the actual situation to identify what is actually going on.
14696        if (false) {
14697            for (int i=0; i<mLaunchingProviders.size(); i++) {
14698                ContentProviderRecord cpr = (ContentProviderRecord)
14699                        mLaunchingProviders.get(i);
14700                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14701                    synchronized (cpr) {
14702                        cpr.launchingApp = null;
14703                        cpr.notifyAll();
14704                    }
14705                }
14706            }
14707        }
14708
14709        skipCurrentReceiverLocked(app);
14710
14711        // Unregister any receivers.
14712        for (int i=app.receivers.size()-1; i>=0; i--) {
14713            removeReceiverLocked(app.receivers.valueAt(i));
14714        }
14715        app.receivers.clear();
14716
14717        // If the app is undergoing backup, tell the backup manager about it
14718        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14719            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14720                    + mBackupTarget.appInfo + " died during backup");
14721            try {
14722                IBackupManager bm = IBackupManager.Stub.asInterface(
14723                        ServiceManager.getService(Context.BACKUP_SERVICE));
14724                bm.agentDisconnected(app.info.packageName);
14725            } catch (RemoteException e) {
14726                // can't happen; backup manager is local
14727            }
14728        }
14729
14730        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14731            ProcessChangeItem item = mPendingProcessChanges.get(i);
14732            if (item.pid == app.pid) {
14733                mPendingProcessChanges.remove(i);
14734                mAvailProcessChanges.add(item);
14735            }
14736        }
14737        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14738
14739        // If the caller is restarting this app, then leave it in its
14740        // current lists and let the caller take care of it.
14741        if (restarting) {
14742            return false;
14743        }
14744
14745        if (!app.persistent || app.isolated) {
14746            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14747                    "Removing non-persistent process during cleanup: " + app);
14748            mProcessNames.remove(app.processName, app.uid);
14749            mIsolatedProcesses.remove(app.uid);
14750            if (mHeavyWeightProcess == app) {
14751                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14752                        mHeavyWeightProcess.userId, 0));
14753                mHeavyWeightProcess = null;
14754            }
14755        } else if (!app.removed) {
14756            // This app is persistent, so we need to keep its record around.
14757            // If it is not already on the pending app list, add it there
14758            // and start a new process for it.
14759            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14760                mPersistentStartingProcesses.add(app);
14761                restart = true;
14762            }
14763        }
14764        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14765                "Clean-up removing on hold: " + app);
14766        mProcessesOnHold.remove(app);
14767
14768        if (app == mHomeProcess) {
14769            mHomeProcess = null;
14770        }
14771        if (app == mPreviousProcess) {
14772            mPreviousProcess = null;
14773        }
14774
14775        if (restart && !app.isolated) {
14776            // We have components that still need to be running in the
14777            // process, so re-launch it.
14778            if (index < 0) {
14779                ProcessList.remove(app.pid);
14780            }
14781            mProcessNames.put(app.processName, app.uid, app);
14782            startProcessLocked(app, "restart", app.processName);
14783            return true;
14784        } else if (app.pid > 0 && app.pid != MY_PID) {
14785            // Goodbye!
14786            boolean removed;
14787            synchronized (mPidsSelfLocked) {
14788                mPidsSelfLocked.remove(app.pid);
14789                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14790            }
14791            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14792            if (app.isolated) {
14793                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14794            }
14795            app.setPid(0);
14796        }
14797        return false;
14798    }
14799
14800    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14801        // Look through the content providers we are waiting to have launched,
14802        // and if any run in this process then either schedule a restart of
14803        // the process or kill the client waiting for it if this process has
14804        // gone bad.
14805        int NL = mLaunchingProviders.size();
14806        boolean restart = false;
14807        for (int i=0; i<NL; i++) {
14808            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14809            if (cpr.launchingApp == app) {
14810                if (!alwaysBad && !app.bad) {
14811                    restart = true;
14812                } else {
14813                    removeDyingProviderLocked(app, cpr, true);
14814                    // cpr should have been removed from mLaunchingProviders
14815                    NL = mLaunchingProviders.size();
14816                    i--;
14817                }
14818            }
14819        }
14820        return restart;
14821    }
14822
14823    // =========================================================
14824    // SERVICES
14825    // =========================================================
14826
14827    @Override
14828    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14829            int flags) {
14830        enforceNotIsolatedCaller("getServices");
14831        synchronized (this) {
14832            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14833        }
14834    }
14835
14836    @Override
14837    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14838        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14839        synchronized (this) {
14840            return mServices.getRunningServiceControlPanelLocked(name);
14841        }
14842    }
14843
14844    @Override
14845    public ComponentName startService(IApplicationThread caller, Intent service,
14846            String resolvedType, int userId) {
14847        enforceNotIsolatedCaller("startService");
14848        // Refuse possible leaked file descriptors
14849        if (service != null && service.hasFileDescriptors() == true) {
14850            throw new IllegalArgumentException("File descriptors passed in Intent");
14851        }
14852
14853        if (DEBUG_SERVICE)
14854            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14855        synchronized(this) {
14856            final int callingPid = Binder.getCallingPid();
14857            final int callingUid = Binder.getCallingUid();
14858            final long origId = Binder.clearCallingIdentity();
14859            ComponentName res = mServices.startServiceLocked(caller, service,
14860                    resolvedType, callingPid, callingUid, userId);
14861            Binder.restoreCallingIdentity(origId);
14862            return res;
14863        }
14864    }
14865
14866    ComponentName startServiceInPackage(int uid,
14867            Intent service, String resolvedType, int userId) {
14868        synchronized(this) {
14869            if (DEBUG_SERVICE)
14870                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14871            final long origId = Binder.clearCallingIdentity();
14872            ComponentName res = mServices.startServiceLocked(null, service,
14873                    resolvedType, -1, uid, userId);
14874            Binder.restoreCallingIdentity(origId);
14875            return res;
14876        }
14877    }
14878
14879    @Override
14880    public int stopService(IApplicationThread caller, Intent service,
14881            String resolvedType, int userId) {
14882        enforceNotIsolatedCaller("stopService");
14883        // Refuse possible leaked file descriptors
14884        if (service != null && service.hasFileDescriptors() == true) {
14885            throw new IllegalArgumentException("File descriptors passed in Intent");
14886        }
14887
14888        synchronized(this) {
14889            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14890        }
14891    }
14892
14893    @Override
14894    public IBinder peekService(Intent service, String resolvedType) {
14895        enforceNotIsolatedCaller("peekService");
14896        // Refuse possible leaked file descriptors
14897        if (service != null && service.hasFileDescriptors() == true) {
14898            throw new IllegalArgumentException("File descriptors passed in Intent");
14899        }
14900        synchronized(this) {
14901            return mServices.peekServiceLocked(service, resolvedType);
14902        }
14903    }
14904
14905    @Override
14906    public boolean stopServiceToken(ComponentName className, IBinder token,
14907            int startId) {
14908        synchronized(this) {
14909            return mServices.stopServiceTokenLocked(className, token, startId);
14910        }
14911    }
14912
14913    @Override
14914    public void setServiceForeground(ComponentName className, IBinder token,
14915            int id, Notification notification, boolean removeNotification) {
14916        synchronized(this) {
14917            mServices.setServiceForegroundLocked(className, token, id, notification,
14918                    removeNotification);
14919        }
14920    }
14921
14922    @Override
14923    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14924            boolean requireFull, String name, String callerPackage) {
14925        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14926                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14927    }
14928
14929    int unsafeConvertIncomingUser(int userId) {
14930        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14931                ? mCurrentUserId : userId;
14932    }
14933
14934    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14935            int allowMode, String name, String callerPackage) {
14936        final int callingUserId = UserHandle.getUserId(callingUid);
14937        if (callingUserId == userId) {
14938            return userId;
14939        }
14940
14941        // Note that we may be accessing mCurrentUserId outside of a lock...
14942        // shouldn't be a big deal, if this is being called outside
14943        // of a locked context there is intrinsically a race with
14944        // the value the caller will receive and someone else changing it.
14945        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14946        // we will switch to the calling user if access to the current user fails.
14947        int targetUserId = unsafeConvertIncomingUser(userId);
14948
14949        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14950            final boolean allow;
14951            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14952                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14953                // If the caller has this permission, they always pass go.  And collect $200.
14954                allow = true;
14955            } else if (allowMode == ALLOW_FULL_ONLY) {
14956                // We require full access, sucks to be you.
14957                allow = false;
14958            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14959                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14960                // If the caller does not have either permission, they are always doomed.
14961                allow = false;
14962            } else if (allowMode == ALLOW_NON_FULL) {
14963                // We are blanket allowing non-full access, you lucky caller!
14964                allow = true;
14965            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14966                // We may or may not allow this depending on whether the two users are
14967                // in the same profile.
14968                synchronized (mUserProfileGroupIdsSelfLocked) {
14969                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14970                            UserInfo.NO_PROFILE_GROUP_ID);
14971                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14972                            UserInfo.NO_PROFILE_GROUP_ID);
14973                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14974                            && callingProfile == targetProfile;
14975                }
14976            } else {
14977                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14978            }
14979            if (!allow) {
14980                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14981                    // In this case, they would like to just execute as their
14982                    // owner user instead of failing.
14983                    targetUserId = callingUserId;
14984                } else {
14985                    StringBuilder builder = new StringBuilder(128);
14986                    builder.append("Permission Denial: ");
14987                    builder.append(name);
14988                    if (callerPackage != null) {
14989                        builder.append(" from ");
14990                        builder.append(callerPackage);
14991                    }
14992                    builder.append(" asks to run as user ");
14993                    builder.append(userId);
14994                    builder.append(" but is calling from user ");
14995                    builder.append(UserHandle.getUserId(callingUid));
14996                    builder.append("; this requires ");
14997                    builder.append(INTERACT_ACROSS_USERS_FULL);
14998                    if (allowMode != ALLOW_FULL_ONLY) {
14999                        builder.append(" or ");
15000                        builder.append(INTERACT_ACROSS_USERS);
15001                    }
15002                    String msg = builder.toString();
15003                    Slog.w(TAG, msg);
15004                    throw new SecurityException(msg);
15005                }
15006            }
15007        }
15008        if (!allowAll && targetUserId < 0) {
15009            throw new IllegalArgumentException(
15010                    "Call does not support special user #" + targetUserId);
15011        }
15012        // Check shell permission
15013        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15014            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15015                    targetUserId)) {
15016                throw new SecurityException("Shell does not have permission to access user "
15017                        + targetUserId + "\n " + Debug.getCallers(3));
15018            }
15019        }
15020        return targetUserId;
15021    }
15022
15023    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15024            String className, int flags) {
15025        boolean result = false;
15026        // For apps that don't have pre-defined UIDs, check for permission
15027        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15028            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15029                if (ActivityManager.checkUidPermission(
15030                        INTERACT_ACROSS_USERS,
15031                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15032                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15033                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15034                            + " requests FLAG_SINGLE_USER, but app does not hold "
15035                            + INTERACT_ACROSS_USERS;
15036                    Slog.w(TAG, msg);
15037                    throw new SecurityException(msg);
15038                }
15039                // Permission passed
15040                result = true;
15041            }
15042        } else if ("system".equals(componentProcessName)) {
15043            result = true;
15044        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15045            // Phone app and persistent apps are allowed to export singleuser providers.
15046            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15047                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15048        }
15049        if (DEBUG_MU) {
15050            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15051                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15052        }
15053        return result;
15054    }
15055
15056    /**
15057     * Checks to see if the caller is in the same app as the singleton
15058     * component, or the component is in a special app. It allows special apps
15059     * to export singleton components but prevents exporting singleton
15060     * components for regular apps.
15061     */
15062    boolean isValidSingletonCall(int callingUid, int componentUid) {
15063        int componentAppId = UserHandle.getAppId(componentUid);
15064        return UserHandle.isSameApp(callingUid, componentUid)
15065                || componentAppId == Process.SYSTEM_UID
15066                || componentAppId == Process.PHONE_UID
15067                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15068                        == PackageManager.PERMISSION_GRANTED;
15069    }
15070
15071    public int bindService(IApplicationThread caller, IBinder token,
15072            Intent service, String resolvedType,
15073            IServiceConnection connection, int flags, int userId) {
15074        enforceNotIsolatedCaller("bindService");
15075
15076        // Refuse possible leaked file descriptors
15077        if (service != null && service.hasFileDescriptors() == true) {
15078            throw new IllegalArgumentException("File descriptors passed in Intent");
15079        }
15080
15081        synchronized(this) {
15082            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15083                    connection, flags, userId);
15084        }
15085    }
15086
15087    public boolean unbindService(IServiceConnection connection) {
15088        synchronized (this) {
15089            return mServices.unbindServiceLocked(connection);
15090        }
15091    }
15092
15093    public void publishService(IBinder token, Intent intent, IBinder service) {
15094        // Refuse possible leaked file descriptors
15095        if (intent != null && intent.hasFileDescriptors() == true) {
15096            throw new IllegalArgumentException("File descriptors passed in Intent");
15097        }
15098
15099        synchronized(this) {
15100            if (!(token instanceof ServiceRecord)) {
15101                throw new IllegalArgumentException("Invalid service token");
15102            }
15103            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15104        }
15105    }
15106
15107    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15108        // Refuse possible leaked file descriptors
15109        if (intent != null && intent.hasFileDescriptors() == true) {
15110            throw new IllegalArgumentException("File descriptors passed in Intent");
15111        }
15112
15113        synchronized(this) {
15114            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15115        }
15116    }
15117
15118    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15119        synchronized(this) {
15120            if (!(token instanceof ServiceRecord)) {
15121                throw new IllegalArgumentException("Invalid service token");
15122            }
15123            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15124        }
15125    }
15126
15127    // =========================================================
15128    // BACKUP AND RESTORE
15129    // =========================================================
15130
15131    // Cause the target app to be launched if necessary and its backup agent
15132    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15133    // activity manager to announce its creation.
15134    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15135        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15136        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15137
15138        synchronized(this) {
15139            // !!! TODO: currently no check here that we're already bound
15140            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15141            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15142            synchronized (stats) {
15143                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15144            }
15145
15146            // Backup agent is now in use, its package can't be stopped.
15147            try {
15148                AppGlobals.getPackageManager().setPackageStoppedState(
15149                        app.packageName, false, UserHandle.getUserId(app.uid));
15150            } catch (RemoteException e) {
15151            } catch (IllegalArgumentException e) {
15152                Slog.w(TAG, "Failed trying to unstop package "
15153                        + app.packageName + ": " + e);
15154            }
15155
15156            BackupRecord r = new BackupRecord(ss, app, backupMode);
15157            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15158                    ? new ComponentName(app.packageName, app.backupAgentName)
15159                    : new ComponentName("android", "FullBackupAgent");
15160            // startProcessLocked() returns existing proc's record if it's already running
15161            ProcessRecord proc = startProcessLocked(app.processName, app,
15162                    false, 0, "backup", hostingName, false, false, false);
15163            if (proc == null) {
15164                Slog.e(TAG, "Unable to start backup agent process " + r);
15165                return false;
15166            }
15167
15168            r.app = proc;
15169            mBackupTarget = r;
15170            mBackupAppName = app.packageName;
15171
15172            // Try not to kill the process during backup
15173            updateOomAdjLocked(proc);
15174
15175            // If the process is already attached, schedule the creation of the backup agent now.
15176            // If it is not yet live, this will be done when it attaches to the framework.
15177            if (proc.thread != null) {
15178                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15179                try {
15180                    proc.thread.scheduleCreateBackupAgent(app,
15181                            compatibilityInfoForPackageLocked(app), backupMode);
15182                } catch (RemoteException e) {
15183                    // Will time out on the backup manager side
15184                }
15185            } else {
15186                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15187            }
15188            // Invariants: at this point, the target app process exists and the application
15189            // is either already running or in the process of coming up.  mBackupTarget and
15190            // mBackupAppName describe the app, so that when it binds back to the AM we
15191            // know that it's scheduled for a backup-agent operation.
15192        }
15193
15194        return true;
15195    }
15196
15197    @Override
15198    public void clearPendingBackup() {
15199        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15200        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15201
15202        synchronized (this) {
15203            mBackupTarget = null;
15204            mBackupAppName = null;
15205        }
15206    }
15207
15208    // A backup agent has just come up
15209    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15210        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15211                + " = " + agent);
15212
15213        synchronized(this) {
15214            if (!agentPackageName.equals(mBackupAppName)) {
15215                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15216                return;
15217            }
15218        }
15219
15220        long oldIdent = Binder.clearCallingIdentity();
15221        try {
15222            IBackupManager bm = IBackupManager.Stub.asInterface(
15223                    ServiceManager.getService(Context.BACKUP_SERVICE));
15224            bm.agentConnected(agentPackageName, agent);
15225        } catch (RemoteException e) {
15226            // can't happen; the backup manager service is local
15227        } catch (Exception e) {
15228            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15229            e.printStackTrace();
15230        } finally {
15231            Binder.restoreCallingIdentity(oldIdent);
15232        }
15233    }
15234
15235    // done with this agent
15236    public void unbindBackupAgent(ApplicationInfo appInfo) {
15237        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15238        if (appInfo == null) {
15239            Slog.w(TAG, "unbind backup agent for null app");
15240            return;
15241        }
15242
15243        synchronized(this) {
15244            try {
15245                if (mBackupAppName == null) {
15246                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15247                    return;
15248                }
15249
15250                if (!mBackupAppName.equals(appInfo.packageName)) {
15251                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15252                    return;
15253                }
15254
15255                // Not backing this app up any more; reset its OOM adjustment
15256                final ProcessRecord proc = mBackupTarget.app;
15257                updateOomAdjLocked(proc);
15258
15259                // If the app crashed during backup, 'thread' will be null here
15260                if (proc.thread != null) {
15261                    try {
15262                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15263                                compatibilityInfoForPackageLocked(appInfo));
15264                    } catch (Exception e) {
15265                        Slog.e(TAG, "Exception when unbinding backup agent:");
15266                        e.printStackTrace();
15267                    }
15268                }
15269            } finally {
15270                mBackupTarget = null;
15271                mBackupAppName = null;
15272            }
15273        }
15274    }
15275    // =========================================================
15276    // BROADCASTS
15277    // =========================================================
15278
15279    private final List getStickiesLocked(String action, IntentFilter filter,
15280            List cur, int userId) {
15281        final ContentResolver resolver = mContext.getContentResolver();
15282        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15283        if (stickies == null) {
15284            return cur;
15285        }
15286        final ArrayList<Intent> list = stickies.get(action);
15287        if (list == null) {
15288            return cur;
15289        }
15290        int N = list.size();
15291        for (int i=0; i<N; i++) {
15292            Intent intent = list.get(i);
15293            if (filter.match(resolver, intent, true, TAG) >= 0) {
15294                if (cur == null) {
15295                    cur = new ArrayList<Intent>();
15296                }
15297                cur.add(intent);
15298            }
15299        }
15300        return cur;
15301    }
15302
15303    boolean isPendingBroadcastProcessLocked(int pid) {
15304        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15305                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15306    }
15307
15308    void skipPendingBroadcastLocked(int pid) {
15309            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15310            for (BroadcastQueue queue : mBroadcastQueues) {
15311                queue.skipPendingBroadcastLocked(pid);
15312            }
15313    }
15314
15315    // The app just attached; send any pending broadcasts that it should receive
15316    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15317        boolean didSomething = false;
15318        for (BroadcastQueue queue : mBroadcastQueues) {
15319            didSomething |= queue.sendPendingBroadcastsLocked(app);
15320        }
15321        return didSomething;
15322    }
15323
15324    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15325            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15326        enforceNotIsolatedCaller("registerReceiver");
15327        int callingUid;
15328        int callingPid;
15329        synchronized(this) {
15330            ProcessRecord callerApp = null;
15331            if (caller != null) {
15332                callerApp = getRecordForAppLocked(caller);
15333                if (callerApp == null) {
15334                    throw new SecurityException(
15335                            "Unable to find app for caller " + caller
15336                            + " (pid=" + Binder.getCallingPid()
15337                            + ") when registering receiver " + receiver);
15338                }
15339                if (callerApp.info.uid != Process.SYSTEM_UID &&
15340                        !callerApp.pkgList.containsKey(callerPackage) &&
15341                        !"android".equals(callerPackage)) {
15342                    throw new SecurityException("Given caller package " + callerPackage
15343                            + " is not running in process " + callerApp);
15344                }
15345                callingUid = callerApp.info.uid;
15346                callingPid = callerApp.pid;
15347            } else {
15348                callerPackage = null;
15349                callingUid = Binder.getCallingUid();
15350                callingPid = Binder.getCallingPid();
15351            }
15352
15353            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15354                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15355
15356            List allSticky = null;
15357
15358            // Look for any matching sticky broadcasts...
15359            Iterator actions = filter.actionsIterator();
15360            if (actions != null) {
15361                while (actions.hasNext()) {
15362                    String action = (String)actions.next();
15363                    allSticky = getStickiesLocked(action, filter, allSticky,
15364                            UserHandle.USER_ALL);
15365                    allSticky = getStickiesLocked(action, filter, allSticky,
15366                            UserHandle.getUserId(callingUid));
15367                }
15368            } else {
15369                allSticky = getStickiesLocked(null, filter, allSticky,
15370                        UserHandle.USER_ALL);
15371                allSticky = getStickiesLocked(null, filter, allSticky,
15372                        UserHandle.getUserId(callingUid));
15373            }
15374
15375            // The first sticky in the list is returned directly back to
15376            // the client.
15377            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15378
15379            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15380                    + ": " + sticky);
15381
15382            if (receiver == null) {
15383                return sticky;
15384            }
15385
15386            ReceiverList rl
15387                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15388            if (rl == null) {
15389                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15390                        userId, receiver);
15391                if (rl.app != null) {
15392                    rl.app.receivers.add(rl);
15393                } else {
15394                    try {
15395                        receiver.asBinder().linkToDeath(rl, 0);
15396                    } catch (RemoteException e) {
15397                        return sticky;
15398                    }
15399                    rl.linkedToDeath = true;
15400                }
15401                mRegisteredReceivers.put(receiver.asBinder(), rl);
15402            } else if (rl.uid != callingUid) {
15403                throw new IllegalArgumentException(
15404                        "Receiver requested to register for uid " + callingUid
15405                        + " was previously registered for uid " + rl.uid);
15406            } else if (rl.pid != callingPid) {
15407                throw new IllegalArgumentException(
15408                        "Receiver requested to register for pid " + callingPid
15409                        + " was previously registered for pid " + rl.pid);
15410            } else if (rl.userId != userId) {
15411                throw new IllegalArgumentException(
15412                        "Receiver requested to register for user " + userId
15413                        + " was previously registered for user " + rl.userId);
15414            }
15415            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15416                    permission, callingUid, userId);
15417            rl.add(bf);
15418            if (!bf.debugCheck()) {
15419                Slog.w(TAG, "==> For Dynamic broadast");
15420            }
15421            mReceiverResolver.addFilter(bf);
15422
15423            // Enqueue broadcasts for all existing stickies that match
15424            // this filter.
15425            if (allSticky != null) {
15426                ArrayList receivers = new ArrayList();
15427                receivers.add(bf);
15428
15429                int N = allSticky.size();
15430                for (int i=0; i<N; i++) {
15431                    Intent intent = (Intent)allSticky.get(i);
15432                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15433                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15434                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15435                            null, null, false, true, true, -1);
15436                    queue.enqueueParallelBroadcastLocked(r);
15437                    queue.scheduleBroadcastsLocked();
15438                }
15439            }
15440
15441            return sticky;
15442        }
15443    }
15444
15445    public void unregisterReceiver(IIntentReceiver receiver) {
15446        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15447
15448        final long origId = Binder.clearCallingIdentity();
15449        try {
15450            boolean doTrim = false;
15451
15452            synchronized(this) {
15453                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15454                if (rl != null) {
15455                    if (rl.curBroadcast != null) {
15456                        BroadcastRecord r = rl.curBroadcast;
15457                        final boolean doNext = finishReceiverLocked(
15458                                receiver.asBinder(), r.resultCode, r.resultData,
15459                                r.resultExtras, r.resultAbort);
15460                        if (doNext) {
15461                            doTrim = true;
15462                            r.queue.processNextBroadcast(false);
15463                        }
15464                    }
15465
15466                    if (rl.app != null) {
15467                        rl.app.receivers.remove(rl);
15468                    }
15469                    removeReceiverLocked(rl);
15470                    if (rl.linkedToDeath) {
15471                        rl.linkedToDeath = false;
15472                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15473                    }
15474                }
15475            }
15476
15477            // If we actually concluded any broadcasts, we might now be able
15478            // to trim the recipients' apps from our working set
15479            if (doTrim) {
15480                trimApplications();
15481                return;
15482            }
15483
15484        } finally {
15485            Binder.restoreCallingIdentity(origId);
15486        }
15487    }
15488
15489    void removeReceiverLocked(ReceiverList rl) {
15490        mRegisteredReceivers.remove(rl.receiver.asBinder());
15491        int N = rl.size();
15492        for (int i=0; i<N; i++) {
15493            mReceiverResolver.removeFilter(rl.get(i));
15494        }
15495    }
15496
15497    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15498        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15499            ProcessRecord r = mLruProcesses.get(i);
15500            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15501                try {
15502                    r.thread.dispatchPackageBroadcast(cmd, packages);
15503                } catch (RemoteException ex) {
15504                }
15505            }
15506        }
15507    }
15508
15509    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15510            int callingUid, int[] users) {
15511        List<ResolveInfo> receivers = null;
15512        try {
15513            HashSet<ComponentName> singleUserReceivers = null;
15514            boolean scannedFirstReceivers = false;
15515            for (int user : users) {
15516                // Skip users that have Shell restrictions
15517                if (callingUid == Process.SHELL_UID
15518                        && getUserManagerLocked().hasUserRestriction(
15519                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15520                    continue;
15521                }
15522                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15523                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15524                if (user != 0 && newReceivers != null) {
15525                    // If this is not the primary user, we need to check for
15526                    // any receivers that should be filtered out.
15527                    for (int i=0; i<newReceivers.size(); i++) {
15528                        ResolveInfo ri = newReceivers.get(i);
15529                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15530                            newReceivers.remove(i);
15531                            i--;
15532                        }
15533                    }
15534                }
15535                if (newReceivers != null && newReceivers.size() == 0) {
15536                    newReceivers = null;
15537                }
15538                if (receivers == null) {
15539                    receivers = newReceivers;
15540                } else if (newReceivers != null) {
15541                    // We need to concatenate the additional receivers
15542                    // found with what we have do far.  This would be easy,
15543                    // but we also need to de-dup any receivers that are
15544                    // singleUser.
15545                    if (!scannedFirstReceivers) {
15546                        // Collect any single user receivers we had already retrieved.
15547                        scannedFirstReceivers = true;
15548                        for (int i=0; i<receivers.size(); i++) {
15549                            ResolveInfo ri = receivers.get(i);
15550                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15551                                ComponentName cn = new ComponentName(
15552                                        ri.activityInfo.packageName, ri.activityInfo.name);
15553                                if (singleUserReceivers == null) {
15554                                    singleUserReceivers = new HashSet<ComponentName>();
15555                                }
15556                                singleUserReceivers.add(cn);
15557                            }
15558                        }
15559                    }
15560                    // Add the new results to the existing results, tracking
15561                    // and de-dupping single user receivers.
15562                    for (int i=0; i<newReceivers.size(); i++) {
15563                        ResolveInfo ri = newReceivers.get(i);
15564                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15565                            ComponentName cn = new ComponentName(
15566                                    ri.activityInfo.packageName, ri.activityInfo.name);
15567                            if (singleUserReceivers == null) {
15568                                singleUserReceivers = new HashSet<ComponentName>();
15569                            }
15570                            if (!singleUserReceivers.contains(cn)) {
15571                                singleUserReceivers.add(cn);
15572                                receivers.add(ri);
15573                            }
15574                        } else {
15575                            receivers.add(ri);
15576                        }
15577                    }
15578                }
15579            }
15580        } catch (RemoteException ex) {
15581            // pm is in same process, this will never happen.
15582        }
15583        return receivers;
15584    }
15585
15586    private final int broadcastIntentLocked(ProcessRecord callerApp,
15587            String callerPackage, Intent intent, String resolvedType,
15588            IIntentReceiver resultTo, int resultCode, String resultData,
15589            Bundle map, String requiredPermission, int appOp,
15590            boolean ordered, boolean sticky, int callingPid, int callingUid,
15591            int userId) {
15592        intent = new Intent(intent);
15593
15594        // By default broadcasts do not go to stopped apps.
15595        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15596
15597        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15598            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15599            + " ordered=" + ordered + " userid=" + userId);
15600        if ((resultTo != null) && !ordered) {
15601            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15602        }
15603
15604        userId = handleIncomingUser(callingPid, callingUid, userId,
15605                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15606
15607        // Make sure that the user who is receiving this broadcast is running.
15608        // If not, we will just skip it.
15609
15610        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15611            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15612                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15613                Slog.w(TAG, "Skipping broadcast of " + intent
15614                        + ": user " + userId + " is stopped");
15615                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15616            }
15617        }
15618
15619        /*
15620         * Prevent non-system code (defined here to be non-persistent
15621         * processes) from sending protected broadcasts.
15622         */
15623        int callingAppId = UserHandle.getAppId(callingUid);
15624        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15625            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15626            || callingAppId == Process.NFC_UID || callingUid == 0) {
15627            // Always okay.
15628        } else if (callerApp == null || !callerApp.persistent) {
15629            try {
15630                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15631                        intent.getAction())) {
15632                    String msg = "Permission Denial: not allowed to send broadcast "
15633                            + intent.getAction() + " from pid="
15634                            + callingPid + ", uid=" + callingUid;
15635                    Slog.w(TAG, msg);
15636                    throw new SecurityException(msg);
15637                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15638                    // Special case for compatibility: we don't want apps to send this,
15639                    // but historically it has not been protected and apps may be using it
15640                    // to poke their own app widget.  So, instead of making it protected,
15641                    // just limit it to the caller.
15642                    if (callerApp == null) {
15643                        String msg = "Permission Denial: not allowed to send broadcast "
15644                                + intent.getAction() + " from unknown caller.";
15645                        Slog.w(TAG, msg);
15646                        throw new SecurityException(msg);
15647                    } else if (intent.getComponent() != null) {
15648                        // They are good enough to send to an explicit component...  verify
15649                        // it is being sent to the calling app.
15650                        if (!intent.getComponent().getPackageName().equals(
15651                                callerApp.info.packageName)) {
15652                            String msg = "Permission Denial: not allowed to send broadcast "
15653                                    + intent.getAction() + " to "
15654                                    + intent.getComponent().getPackageName() + " from "
15655                                    + callerApp.info.packageName;
15656                            Slog.w(TAG, msg);
15657                            throw new SecurityException(msg);
15658                        }
15659                    } else {
15660                        // Limit broadcast to their own package.
15661                        intent.setPackage(callerApp.info.packageName);
15662                    }
15663                }
15664            } catch (RemoteException e) {
15665                Slog.w(TAG, "Remote exception", e);
15666                return ActivityManager.BROADCAST_SUCCESS;
15667            }
15668        }
15669
15670        final String action = intent.getAction();
15671        if (action != null) {
15672            switch (action) {
15673                case Intent.ACTION_UID_REMOVED:
15674                case Intent.ACTION_PACKAGE_REMOVED:
15675                case Intent.ACTION_PACKAGE_CHANGED:
15676                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15677                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15678                    // Handle special intents: if this broadcast is from the package
15679                    // manager about a package being removed, we need to remove all of
15680                    // its activities from the history stack.
15681                    if (checkComponentPermission(
15682                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15683                            callingPid, callingUid, -1, true)
15684                            != PackageManager.PERMISSION_GRANTED) {
15685                        String msg = "Permission Denial: " + intent.getAction()
15686                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15687                                + ", uid=" + callingUid + ")"
15688                                + " requires "
15689                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15690                        Slog.w(TAG, msg);
15691                        throw new SecurityException(msg);
15692                    }
15693                    switch (action) {
15694                        case Intent.ACTION_UID_REMOVED:
15695                            final Bundle intentExtras = intent.getExtras();
15696                            final int uid = intentExtras != null
15697                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15698                            if (uid >= 0) {
15699                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15700                                synchronized (bs) {
15701                                    bs.removeUidStatsLocked(uid);
15702                                }
15703                                mAppOpsService.uidRemoved(uid);
15704                            }
15705                            break;
15706                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15707                            // If resources are unavailable just force stop all those packages
15708                            // and flush the attribute cache as well.
15709                            String list[] =
15710                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15711                            if (list != null && list.length > 0) {
15712                                for (int i = 0; i < list.length; i++) {
15713                                    forceStopPackageLocked(list[i], -1, false, true, true,
15714                                            false, false, userId, "storage unmount");
15715                                }
15716                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15717                                sendPackageBroadcastLocked(
15718                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15719                                        userId);
15720                            }
15721                            break;
15722                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15723                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15724                            break;
15725                        case Intent.ACTION_PACKAGE_REMOVED:
15726                        case Intent.ACTION_PACKAGE_CHANGED:
15727                            Uri data = intent.getData();
15728                            String ssp;
15729                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15730                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15731                                boolean fullUninstall = removed &&
15732                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15733                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15734                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15735                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15736                                            false, true, true, false, fullUninstall, userId,
15737                                            removed ? "pkg removed" : "pkg changed");
15738                                }
15739                                if (removed) {
15740                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15741                                            new String[] {ssp}, userId);
15742                                    if (fullUninstall) {
15743                                        mAppOpsService.packageRemoved(
15744                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15745
15746                                        // Remove all permissions granted from/to this package
15747                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15748
15749                                        removeTasksByPackageNameLocked(ssp, userId);
15750                                    }
15751                                } else {
15752                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15753                                }
15754                            }
15755                            break;
15756                    }
15757                    break;
15758                case Intent.ACTION_PACKAGE_ADDED:
15759                    // Special case for adding a package: by default turn on compatibility mode.
15760                    Uri data = intent.getData();
15761                    String ssp;
15762                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15763                        final boolean replacing =
15764                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15765                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15766
15767                        if (replacing) {
15768                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15769                        }
15770                    }
15771                    break;
15772                case Intent.ACTION_TIMEZONE_CHANGED:
15773                    // If this is the time zone changed action, queue up a message that will reset
15774                    // the timezone of all currently running processes. This message will get
15775                    // queued up before the broadcast happens.
15776                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15777                    break;
15778                case Intent.ACTION_TIME_CHANGED:
15779                    // If the user set the time, let all running processes know.
15780                    final int is24Hour =
15781                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15782                                    : 0;
15783                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15784                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15785                    synchronized (stats) {
15786                        stats.noteCurrentTimeChangedLocked();
15787                    }
15788                    break;
15789                case Intent.ACTION_CLEAR_DNS_CACHE:
15790                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15791                    break;
15792                case Proxy.PROXY_CHANGE_ACTION:
15793                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15794                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15795                    break;
15796            }
15797        }
15798
15799        // Add to the sticky list if requested.
15800        if (sticky) {
15801            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15802                    callingPid, callingUid)
15803                    != PackageManager.PERMISSION_GRANTED) {
15804                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15805                        + callingPid + ", uid=" + callingUid
15806                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15807                Slog.w(TAG, msg);
15808                throw new SecurityException(msg);
15809            }
15810            if (requiredPermission != null) {
15811                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15812                        + " and enforce permission " + requiredPermission);
15813                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15814            }
15815            if (intent.getComponent() != null) {
15816                throw new SecurityException(
15817                        "Sticky broadcasts can't target a specific component");
15818            }
15819            // We use userId directly here, since the "all" target is maintained
15820            // as a separate set of sticky broadcasts.
15821            if (userId != UserHandle.USER_ALL) {
15822                // But first, if this is not a broadcast to all users, then
15823                // make sure it doesn't conflict with an existing broadcast to
15824                // all users.
15825                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15826                        UserHandle.USER_ALL);
15827                if (stickies != null) {
15828                    ArrayList<Intent> list = stickies.get(intent.getAction());
15829                    if (list != null) {
15830                        int N = list.size();
15831                        int i;
15832                        for (i=0; i<N; i++) {
15833                            if (intent.filterEquals(list.get(i))) {
15834                                throw new IllegalArgumentException(
15835                                        "Sticky broadcast " + intent + " for user "
15836                                        + userId + " conflicts with existing global broadcast");
15837                            }
15838                        }
15839                    }
15840                }
15841            }
15842            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15843            if (stickies == null) {
15844                stickies = new ArrayMap<String, ArrayList<Intent>>();
15845                mStickyBroadcasts.put(userId, stickies);
15846            }
15847            ArrayList<Intent> list = stickies.get(intent.getAction());
15848            if (list == null) {
15849                list = new ArrayList<Intent>();
15850                stickies.put(intent.getAction(), list);
15851            }
15852            int N = list.size();
15853            int i;
15854            for (i=0; i<N; i++) {
15855                if (intent.filterEquals(list.get(i))) {
15856                    // This sticky already exists, replace it.
15857                    list.set(i, new Intent(intent));
15858                    break;
15859                }
15860            }
15861            if (i >= N) {
15862                list.add(new Intent(intent));
15863            }
15864        }
15865
15866        int[] users;
15867        if (userId == UserHandle.USER_ALL) {
15868            // Caller wants broadcast to go to all started users.
15869            users = mStartedUserArray;
15870        } else {
15871            // Caller wants broadcast to go to one specific user.
15872            users = new int[] {userId};
15873        }
15874
15875        // Figure out who all will receive this broadcast.
15876        List receivers = null;
15877        List<BroadcastFilter> registeredReceivers = null;
15878        // Need to resolve the intent to interested receivers...
15879        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15880                 == 0) {
15881            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15882        }
15883        if (intent.getComponent() == null) {
15884            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15885                // Query one target user at a time, excluding shell-restricted users
15886                UserManagerService ums = getUserManagerLocked();
15887                for (int i = 0; i < users.length; i++) {
15888                    if (ums.hasUserRestriction(
15889                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15890                        continue;
15891                    }
15892                    List<BroadcastFilter> registeredReceiversForUser =
15893                            mReceiverResolver.queryIntent(intent,
15894                                    resolvedType, false, users[i]);
15895                    if (registeredReceivers == null) {
15896                        registeredReceivers = registeredReceiversForUser;
15897                    } else if (registeredReceiversForUser != null) {
15898                        registeredReceivers.addAll(registeredReceiversForUser);
15899                    }
15900                }
15901            } else {
15902                registeredReceivers = mReceiverResolver.queryIntent(intent,
15903                        resolvedType, false, userId);
15904            }
15905        }
15906
15907        final boolean replacePending =
15908                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15909
15910        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15911                + " replacePending=" + replacePending);
15912
15913        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15914        if (!ordered && NR > 0) {
15915            // If we are not serializing this broadcast, then send the
15916            // registered receivers separately so they don't wait for the
15917            // components to be launched.
15918            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15919            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15920                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15921                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15922                    ordered, sticky, false, userId);
15923            if (DEBUG_BROADCAST) Slog.v(
15924                    TAG, "Enqueueing parallel broadcast " + r);
15925            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15926            if (!replaced) {
15927                queue.enqueueParallelBroadcastLocked(r);
15928                queue.scheduleBroadcastsLocked();
15929            }
15930            registeredReceivers = null;
15931            NR = 0;
15932        }
15933
15934        // Merge into one list.
15935        int ir = 0;
15936        if (receivers != null) {
15937            // A special case for PACKAGE_ADDED: do not allow the package
15938            // being added to see this broadcast.  This prevents them from
15939            // using this as a back door to get run as soon as they are
15940            // installed.  Maybe in the future we want to have a special install
15941            // broadcast or such for apps, but we'd like to deliberately make
15942            // this decision.
15943            String skipPackages[] = null;
15944            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15945                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15946                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15947                Uri data = intent.getData();
15948                if (data != null) {
15949                    String pkgName = data.getSchemeSpecificPart();
15950                    if (pkgName != null) {
15951                        skipPackages = new String[] { pkgName };
15952                    }
15953                }
15954            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15955                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15956            }
15957            if (skipPackages != null && (skipPackages.length > 0)) {
15958                for (String skipPackage : skipPackages) {
15959                    if (skipPackage != null) {
15960                        int NT = receivers.size();
15961                        for (int it=0; it<NT; it++) {
15962                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15963                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15964                                receivers.remove(it);
15965                                it--;
15966                                NT--;
15967                            }
15968                        }
15969                    }
15970                }
15971            }
15972
15973            int NT = receivers != null ? receivers.size() : 0;
15974            int it = 0;
15975            ResolveInfo curt = null;
15976            BroadcastFilter curr = null;
15977            while (it < NT && ir < NR) {
15978                if (curt == null) {
15979                    curt = (ResolveInfo)receivers.get(it);
15980                }
15981                if (curr == null) {
15982                    curr = registeredReceivers.get(ir);
15983                }
15984                if (curr.getPriority() >= curt.priority) {
15985                    // Insert this broadcast record into the final list.
15986                    receivers.add(it, curr);
15987                    ir++;
15988                    curr = null;
15989                    it++;
15990                    NT++;
15991                } else {
15992                    // Skip to the next ResolveInfo in the final list.
15993                    it++;
15994                    curt = null;
15995                }
15996            }
15997        }
15998        while (ir < NR) {
15999            if (receivers == null) {
16000                receivers = new ArrayList();
16001            }
16002            receivers.add(registeredReceivers.get(ir));
16003            ir++;
16004        }
16005
16006        if ((receivers != null && receivers.size() > 0)
16007                || resultTo != null) {
16008            BroadcastQueue queue = broadcastQueueForIntent(intent);
16009            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16010                    callerPackage, callingPid, callingUid, resolvedType,
16011                    requiredPermission, appOp, receivers, resultTo, resultCode,
16012                    resultData, map, ordered, sticky, false, userId);
16013            if (DEBUG_BROADCAST) Slog.v(
16014                    TAG, "Enqueueing ordered broadcast " + r
16015                    + ": prev had " + queue.mOrderedBroadcasts.size());
16016            if (DEBUG_BROADCAST) {
16017                int seq = r.intent.getIntExtra("seq", -1);
16018                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16019            }
16020            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16021            if (!replaced) {
16022                queue.enqueueOrderedBroadcastLocked(r);
16023                queue.scheduleBroadcastsLocked();
16024            }
16025        }
16026
16027        return ActivityManager.BROADCAST_SUCCESS;
16028    }
16029
16030    final Intent verifyBroadcastLocked(Intent intent) {
16031        // Refuse possible leaked file descriptors
16032        if (intent != null && intent.hasFileDescriptors() == true) {
16033            throw new IllegalArgumentException("File descriptors passed in Intent");
16034        }
16035
16036        int flags = intent.getFlags();
16037
16038        if (!mProcessesReady) {
16039            // if the caller really truly claims to know what they're doing, go
16040            // ahead and allow the broadcast without launching any receivers
16041            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16042                intent = new Intent(intent);
16043                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16044            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16045                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16046                        + " before boot completion");
16047                throw new IllegalStateException("Cannot broadcast before boot completed");
16048            }
16049        }
16050
16051        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16052            throw new IllegalArgumentException(
16053                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16054        }
16055
16056        return intent;
16057    }
16058
16059    public final int broadcastIntent(IApplicationThread caller,
16060            Intent intent, String resolvedType, IIntentReceiver resultTo,
16061            int resultCode, String resultData, Bundle map,
16062            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16063        enforceNotIsolatedCaller("broadcastIntent");
16064        synchronized(this) {
16065            intent = verifyBroadcastLocked(intent);
16066
16067            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16068            final int callingPid = Binder.getCallingPid();
16069            final int callingUid = Binder.getCallingUid();
16070            final long origId = Binder.clearCallingIdentity();
16071            int res = broadcastIntentLocked(callerApp,
16072                    callerApp != null ? callerApp.info.packageName : null,
16073                    intent, resolvedType, resultTo,
16074                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16075                    callingPid, callingUid, userId);
16076            Binder.restoreCallingIdentity(origId);
16077            return res;
16078        }
16079    }
16080
16081    int broadcastIntentInPackage(String packageName, int uid,
16082            Intent intent, String resolvedType, IIntentReceiver resultTo,
16083            int resultCode, String resultData, Bundle map,
16084            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16085        synchronized(this) {
16086            intent = verifyBroadcastLocked(intent);
16087
16088            final long origId = Binder.clearCallingIdentity();
16089            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16090                    resultTo, resultCode, resultData, map, requiredPermission,
16091                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16092            Binder.restoreCallingIdentity(origId);
16093            return res;
16094        }
16095    }
16096
16097    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16098        // Refuse possible leaked file descriptors
16099        if (intent != null && intent.hasFileDescriptors() == true) {
16100            throw new IllegalArgumentException("File descriptors passed in Intent");
16101        }
16102
16103        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16104                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16105
16106        synchronized(this) {
16107            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16108                    != PackageManager.PERMISSION_GRANTED) {
16109                String msg = "Permission Denial: unbroadcastIntent() from pid="
16110                        + Binder.getCallingPid()
16111                        + ", uid=" + Binder.getCallingUid()
16112                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16113                Slog.w(TAG, msg);
16114                throw new SecurityException(msg);
16115            }
16116            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16117            if (stickies != null) {
16118                ArrayList<Intent> list = stickies.get(intent.getAction());
16119                if (list != null) {
16120                    int N = list.size();
16121                    int i;
16122                    for (i=0; i<N; i++) {
16123                        if (intent.filterEquals(list.get(i))) {
16124                            list.remove(i);
16125                            break;
16126                        }
16127                    }
16128                    if (list.size() <= 0) {
16129                        stickies.remove(intent.getAction());
16130                    }
16131                }
16132                if (stickies.size() <= 0) {
16133                    mStickyBroadcasts.remove(userId);
16134                }
16135            }
16136        }
16137    }
16138
16139    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16140            String resultData, Bundle resultExtras, boolean resultAbort) {
16141        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16142        if (r == null) {
16143            Slog.w(TAG, "finishReceiver called but not found on queue");
16144            return false;
16145        }
16146
16147        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16148    }
16149
16150    void backgroundServicesFinishedLocked(int userId) {
16151        for (BroadcastQueue queue : mBroadcastQueues) {
16152            queue.backgroundServicesFinishedLocked(userId);
16153        }
16154    }
16155
16156    public void finishReceiver(IBinder who, int resultCode, String resultData,
16157            Bundle resultExtras, boolean resultAbort) {
16158        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16159
16160        // Refuse possible leaked file descriptors
16161        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16162            throw new IllegalArgumentException("File descriptors passed in Bundle");
16163        }
16164
16165        final long origId = Binder.clearCallingIdentity();
16166        try {
16167            boolean doNext = false;
16168            BroadcastRecord r;
16169
16170            synchronized(this) {
16171                r = broadcastRecordForReceiverLocked(who);
16172                if (r != null) {
16173                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16174                        resultData, resultExtras, resultAbort, true);
16175                }
16176            }
16177
16178            if (doNext) {
16179                r.queue.processNextBroadcast(false);
16180            }
16181            trimApplications();
16182        } finally {
16183            Binder.restoreCallingIdentity(origId);
16184        }
16185    }
16186
16187    // =========================================================
16188    // INSTRUMENTATION
16189    // =========================================================
16190
16191    public boolean startInstrumentation(ComponentName className,
16192            String profileFile, int flags, Bundle arguments,
16193            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16194            int userId, String abiOverride) {
16195        enforceNotIsolatedCaller("startInstrumentation");
16196        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16197                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16198        // Refuse possible leaked file descriptors
16199        if (arguments != null && arguments.hasFileDescriptors()) {
16200            throw new IllegalArgumentException("File descriptors passed in Bundle");
16201        }
16202
16203        synchronized(this) {
16204            InstrumentationInfo ii = null;
16205            ApplicationInfo ai = null;
16206            try {
16207                ii = mContext.getPackageManager().getInstrumentationInfo(
16208                    className, STOCK_PM_FLAGS);
16209                ai = AppGlobals.getPackageManager().getApplicationInfo(
16210                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16211            } catch (PackageManager.NameNotFoundException e) {
16212            } catch (RemoteException e) {
16213            }
16214            if (ii == null) {
16215                reportStartInstrumentationFailure(watcher, className,
16216                        "Unable to find instrumentation info for: " + className);
16217                return false;
16218            }
16219            if (ai == null) {
16220                reportStartInstrumentationFailure(watcher, className,
16221                        "Unable to find instrumentation target package: " + ii.targetPackage);
16222                return false;
16223            }
16224
16225            int match = mContext.getPackageManager().checkSignatures(
16226                    ii.targetPackage, ii.packageName);
16227            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16228                String msg = "Permission Denial: starting instrumentation "
16229                        + className + " from pid="
16230                        + Binder.getCallingPid()
16231                        + ", uid=" + Binder.getCallingPid()
16232                        + " not allowed because package " + ii.packageName
16233                        + " does not have a signature matching the target "
16234                        + ii.targetPackage;
16235                reportStartInstrumentationFailure(watcher, className, msg);
16236                throw new SecurityException(msg);
16237            }
16238
16239            final long origId = Binder.clearCallingIdentity();
16240            // Instrumentation can kill and relaunch even persistent processes
16241            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16242                    "start instr");
16243            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16244            app.instrumentationClass = className;
16245            app.instrumentationInfo = ai;
16246            app.instrumentationProfileFile = profileFile;
16247            app.instrumentationArguments = arguments;
16248            app.instrumentationWatcher = watcher;
16249            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16250            app.instrumentationResultClass = className;
16251            Binder.restoreCallingIdentity(origId);
16252        }
16253
16254        return true;
16255    }
16256
16257    /**
16258     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16259     * error to the logs, but if somebody is watching, send the report there too.  This enables
16260     * the "am" command to report errors with more information.
16261     *
16262     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16263     * @param cn The component name of the instrumentation.
16264     * @param report The error report.
16265     */
16266    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16267            ComponentName cn, String report) {
16268        Slog.w(TAG, report);
16269        try {
16270            if (watcher != null) {
16271                Bundle results = new Bundle();
16272                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16273                results.putString("Error", report);
16274                watcher.instrumentationStatus(cn, -1, results);
16275            }
16276        } catch (RemoteException e) {
16277            Slog.w(TAG, e);
16278        }
16279    }
16280
16281    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16282        if (app.instrumentationWatcher != null) {
16283            try {
16284                // NOTE:  IInstrumentationWatcher *must* be oneway here
16285                app.instrumentationWatcher.instrumentationFinished(
16286                    app.instrumentationClass,
16287                    resultCode,
16288                    results);
16289            } catch (RemoteException e) {
16290            }
16291        }
16292        if (app.instrumentationUiAutomationConnection != null) {
16293            try {
16294                app.instrumentationUiAutomationConnection.shutdown();
16295            } catch (RemoteException re) {
16296                /* ignore */
16297            }
16298            // Only a UiAutomation can set this flag and now that
16299            // it is finished we make sure it is reset to its default.
16300            mUserIsMonkey = false;
16301        }
16302        app.instrumentationWatcher = null;
16303        app.instrumentationUiAutomationConnection = null;
16304        app.instrumentationClass = null;
16305        app.instrumentationInfo = null;
16306        app.instrumentationProfileFile = null;
16307        app.instrumentationArguments = null;
16308
16309        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16310                "finished inst");
16311    }
16312
16313    public void finishInstrumentation(IApplicationThread target,
16314            int resultCode, Bundle results) {
16315        int userId = UserHandle.getCallingUserId();
16316        // Refuse possible leaked file descriptors
16317        if (results != null && results.hasFileDescriptors()) {
16318            throw new IllegalArgumentException("File descriptors passed in Intent");
16319        }
16320
16321        synchronized(this) {
16322            ProcessRecord app = getRecordForAppLocked(target);
16323            if (app == null) {
16324                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16325                return;
16326            }
16327            final long origId = Binder.clearCallingIdentity();
16328            finishInstrumentationLocked(app, resultCode, results);
16329            Binder.restoreCallingIdentity(origId);
16330        }
16331    }
16332
16333    // =========================================================
16334    // CONFIGURATION
16335    // =========================================================
16336
16337    public ConfigurationInfo getDeviceConfigurationInfo() {
16338        ConfigurationInfo config = new ConfigurationInfo();
16339        synchronized (this) {
16340            config.reqTouchScreen = mConfiguration.touchscreen;
16341            config.reqKeyboardType = mConfiguration.keyboard;
16342            config.reqNavigation = mConfiguration.navigation;
16343            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16344                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16345                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16346            }
16347            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16348                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16349                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16350            }
16351            config.reqGlEsVersion = GL_ES_VERSION;
16352        }
16353        return config;
16354    }
16355
16356    ActivityStack getFocusedStack() {
16357        return mStackSupervisor.getFocusedStack();
16358    }
16359
16360    public Configuration getConfiguration() {
16361        Configuration ci;
16362        synchronized(this) {
16363            ci = new Configuration(mConfiguration);
16364        }
16365        return ci;
16366    }
16367
16368    public void updatePersistentConfiguration(Configuration values) {
16369        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16370                "updateConfiguration()");
16371        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16372                "updateConfiguration()");
16373        if (values == null) {
16374            throw new NullPointerException("Configuration must not be null");
16375        }
16376
16377        synchronized(this) {
16378            final long origId = Binder.clearCallingIdentity();
16379            updateConfigurationLocked(values, null, true, false);
16380            Binder.restoreCallingIdentity(origId);
16381        }
16382    }
16383
16384    public void updateConfiguration(Configuration values) {
16385        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16386                "updateConfiguration()");
16387
16388        synchronized(this) {
16389            if (values == null && mWindowManager != null) {
16390                // sentinel: fetch the current configuration from the window manager
16391                values = mWindowManager.computeNewConfiguration();
16392            }
16393
16394            if (mWindowManager != null) {
16395                mProcessList.applyDisplaySize(mWindowManager);
16396            }
16397
16398            final long origId = Binder.clearCallingIdentity();
16399            if (values != null) {
16400                Settings.System.clearConfiguration(values);
16401            }
16402            updateConfigurationLocked(values, null, false, false);
16403            Binder.restoreCallingIdentity(origId);
16404        }
16405    }
16406
16407    /**
16408     * Do either or both things: (1) change the current configuration, and (2)
16409     * make sure the given activity is running with the (now) current
16410     * configuration.  Returns true if the activity has been left running, or
16411     * false if <var>starting</var> is being destroyed to match the new
16412     * configuration.
16413     * @param persistent TODO
16414     */
16415    boolean updateConfigurationLocked(Configuration values,
16416            ActivityRecord starting, boolean persistent, boolean initLocale) {
16417        int changes = 0;
16418
16419        if (values != null) {
16420            Configuration newConfig = new Configuration(mConfiguration);
16421            changes = newConfig.updateFrom(values);
16422            if (changes != 0) {
16423                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16424                    Slog.i(TAG, "Updating configuration to: " + values);
16425                }
16426
16427                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16428
16429                if (values.locale != null && !initLocale) {
16430                    saveLocaleLocked(values.locale,
16431                                     !values.locale.equals(mConfiguration.locale),
16432                                     values.userSetLocale);
16433                }
16434
16435                mConfigurationSeq++;
16436                if (mConfigurationSeq <= 0) {
16437                    mConfigurationSeq = 1;
16438                }
16439                newConfig.seq = mConfigurationSeq;
16440                mConfiguration = newConfig;
16441                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16442                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16443                //mUsageStatsService.noteStartConfig(newConfig);
16444
16445                final Configuration configCopy = new Configuration(mConfiguration);
16446
16447                // TODO: If our config changes, should we auto dismiss any currently
16448                // showing dialogs?
16449                mShowDialogs = shouldShowDialogs(newConfig);
16450
16451                AttributeCache ac = AttributeCache.instance();
16452                if (ac != null) {
16453                    ac.updateConfiguration(configCopy);
16454                }
16455
16456                // Make sure all resources in our process are updated
16457                // right now, so that anyone who is going to retrieve
16458                // resource values after we return will be sure to get
16459                // the new ones.  This is especially important during
16460                // boot, where the first config change needs to guarantee
16461                // all resources have that config before following boot
16462                // code is executed.
16463                mSystemThread.applyConfigurationToResources(configCopy);
16464
16465                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16466                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16467                    msg.obj = new Configuration(configCopy);
16468                    mHandler.sendMessage(msg);
16469                }
16470
16471                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16472                    ProcessRecord app = mLruProcesses.get(i);
16473                    try {
16474                        if (app.thread != null) {
16475                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16476                                    + app.processName + " new config " + mConfiguration);
16477                            app.thread.scheduleConfigurationChanged(configCopy);
16478                        }
16479                    } catch (Exception e) {
16480                    }
16481                }
16482                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16483                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16484                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16485                        | Intent.FLAG_RECEIVER_FOREGROUND);
16486                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16487                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16488                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16489                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16490                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16491                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16492                    broadcastIntentLocked(null, null, intent,
16493                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16494                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16495                }
16496            }
16497        }
16498
16499        boolean kept = true;
16500        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16501        // mainStack is null during startup.
16502        if (mainStack != null) {
16503            if (changes != 0 && starting == null) {
16504                // If the configuration changed, and the caller is not already
16505                // in the process of starting an activity, then find the top
16506                // activity to check if its configuration needs to change.
16507                starting = mainStack.topRunningActivityLocked(null);
16508            }
16509
16510            if (starting != null) {
16511                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16512                // And we need to make sure at this point that all other activities
16513                // are made visible with the correct configuration.
16514                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16515            }
16516        }
16517
16518        if (values != null && mWindowManager != null) {
16519            mWindowManager.setNewConfiguration(mConfiguration);
16520        }
16521
16522        return kept;
16523    }
16524
16525    /**
16526     * Decide based on the configuration whether we should shouw the ANR,
16527     * crash, etc dialogs.  The idea is that if there is no affordnace to
16528     * press the on-screen buttons, we shouldn't show the dialog.
16529     *
16530     * A thought: SystemUI might also want to get told about this, the Power
16531     * dialog / global actions also might want different behaviors.
16532     */
16533    private static final boolean shouldShowDialogs(Configuration config) {
16534        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16535                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16536    }
16537
16538    /**
16539     * Save the locale.  You must be inside a synchronized (this) block.
16540     */
16541    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16542        if(isDiff) {
16543            SystemProperties.set("user.language", l.getLanguage());
16544            SystemProperties.set("user.region", l.getCountry());
16545        }
16546
16547        if(isPersist) {
16548            SystemProperties.set("persist.sys.language", l.getLanguage());
16549            SystemProperties.set("persist.sys.country", l.getCountry());
16550            SystemProperties.set("persist.sys.localevar", l.getVariant());
16551
16552            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16553        }
16554    }
16555
16556    @Override
16557    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16558        synchronized (this) {
16559            ActivityRecord srec = ActivityRecord.forToken(token);
16560            if (srec.task != null && srec.task.stack != null) {
16561                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16562            }
16563        }
16564        return false;
16565    }
16566
16567    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16568            Intent resultData) {
16569
16570        synchronized (this) {
16571            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16572            if (stack != null) {
16573                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16574            }
16575            return false;
16576        }
16577    }
16578
16579    public int getLaunchedFromUid(IBinder activityToken) {
16580        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16581        if (srec == null) {
16582            return -1;
16583        }
16584        return srec.launchedFromUid;
16585    }
16586
16587    public String getLaunchedFromPackage(IBinder activityToken) {
16588        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16589        if (srec == null) {
16590            return null;
16591        }
16592        return srec.launchedFromPackage;
16593    }
16594
16595    // =========================================================
16596    // LIFETIME MANAGEMENT
16597    // =========================================================
16598
16599    // Returns which broadcast queue the app is the current [or imminent] receiver
16600    // on, or 'null' if the app is not an active broadcast recipient.
16601    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16602        BroadcastRecord r = app.curReceiver;
16603        if (r != null) {
16604            return r.queue;
16605        }
16606
16607        // It's not the current receiver, but it might be starting up to become one
16608        synchronized (this) {
16609            for (BroadcastQueue queue : mBroadcastQueues) {
16610                r = queue.mPendingBroadcast;
16611                if (r != null && r.curApp == app) {
16612                    // found it; report which queue it's in
16613                    return queue;
16614                }
16615            }
16616        }
16617
16618        return null;
16619    }
16620
16621    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16622            boolean doingAll, long now) {
16623        if (mAdjSeq == app.adjSeq) {
16624            // This adjustment has already been computed.
16625            return app.curRawAdj;
16626        }
16627
16628        if (app.thread == null) {
16629            app.adjSeq = mAdjSeq;
16630            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16631            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16632            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16633        }
16634
16635        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16636        app.adjSource = null;
16637        app.adjTarget = null;
16638        app.empty = false;
16639        app.cached = false;
16640
16641        final int activitiesSize = app.activities.size();
16642
16643        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16644            // The max adjustment doesn't allow this app to be anything
16645            // below foreground, so it is not worth doing work for it.
16646            app.adjType = "fixed";
16647            app.adjSeq = mAdjSeq;
16648            app.curRawAdj = app.maxAdj;
16649            app.foregroundActivities = false;
16650            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16651            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16652            // System processes can do UI, and when they do we want to have
16653            // them trim their memory after the user leaves the UI.  To
16654            // facilitate this, here we need to determine whether or not it
16655            // is currently showing UI.
16656            app.systemNoUi = true;
16657            if (app == TOP_APP) {
16658                app.systemNoUi = false;
16659            } else if (activitiesSize > 0) {
16660                for (int j = 0; j < activitiesSize; j++) {
16661                    final ActivityRecord r = app.activities.get(j);
16662                    if (r.visible) {
16663                        app.systemNoUi = false;
16664                    }
16665                }
16666            }
16667            if (!app.systemNoUi) {
16668                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16669            }
16670            return (app.curAdj=app.maxAdj);
16671        }
16672
16673        app.systemNoUi = false;
16674
16675        // Determine the importance of the process, starting with most
16676        // important to least, and assign an appropriate OOM adjustment.
16677        int adj;
16678        int schedGroup;
16679        int procState;
16680        boolean foregroundActivities = false;
16681        BroadcastQueue queue;
16682        if (app == TOP_APP) {
16683            // The last app on the list is the foreground app.
16684            adj = ProcessList.FOREGROUND_APP_ADJ;
16685            schedGroup = Process.THREAD_GROUP_DEFAULT;
16686            app.adjType = "top-activity";
16687            foregroundActivities = true;
16688            procState = ActivityManager.PROCESS_STATE_TOP;
16689        } else if (app.instrumentationClass != null) {
16690            // Don't want to kill running instrumentation.
16691            adj = ProcessList.FOREGROUND_APP_ADJ;
16692            schedGroup = Process.THREAD_GROUP_DEFAULT;
16693            app.adjType = "instrumentation";
16694            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16695        } else if ((queue = isReceivingBroadcast(app)) != null) {
16696            // An app that is currently receiving a broadcast also
16697            // counts as being in the foreground for OOM killer purposes.
16698            // It's placed in a sched group based on the nature of the
16699            // broadcast as reflected by which queue it's active in.
16700            adj = ProcessList.FOREGROUND_APP_ADJ;
16701            schedGroup = (queue == mFgBroadcastQueue)
16702                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16703            app.adjType = "broadcast";
16704            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16705        } else if (app.executingServices.size() > 0) {
16706            // An app that is currently executing a service callback also
16707            // counts as being in the foreground.
16708            adj = ProcessList.FOREGROUND_APP_ADJ;
16709            schedGroup = app.execServicesFg ?
16710                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16711            app.adjType = "exec-service";
16712            procState = ActivityManager.PROCESS_STATE_SERVICE;
16713            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16714        } else {
16715            // As far as we know the process is empty.  We may change our mind later.
16716            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16717            // At this point we don't actually know the adjustment.  Use the cached adj
16718            // value that the caller wants us to.
16719            adj = cachedAdj;
16720            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16721            app.cached = true;
16722            app.empty = true;
16723            app.adjType = "cch-empty";
16724        }
16725
16726        // Examine all activities if not already foreground.
16727        if (!foregroundActivities && activitiesSize > 0) {
16728            for (int j = 0; j < activitiesSize; j++) {
16729                final ActivityRecord r = app.activities.get(j);
16730                if (r.app != app) {
16731                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16732                            + app + "?!?");
16733                    continue;
16734                }
16735                if (r.visible) {
16736                    // App has a visible activity; only upgrade adjustment.
16737                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16738                        adj = ProcessList.VISIBLE_APP_ADJ;
16739                        app.adjType = "visible";
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                    break;
16749                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16750                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16751                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16752                        app.adjType = "pausing";
16753                    }
16754                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16755                        procState = ActivityManager.PROCESS_STATE_TOP;
16756                    }
16757                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16758                    app.cached = false;
16759                    app.empty = false;
16760                    foregroundActivities = true;
16761                } else if (r.state == ActivityState.STOPPING) {
16762                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16763                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16764                        app.adjType = "stopping";
16765                    }
16766                    // For the process state, we will at this point consider the
16767                    // process to be cached.  It will be cached either as an activity
16768                    // or empty depending on whether the activity is finishing.  We do
16769                    // this so that we can treat the process as cached for purposes of
16770                    // memory trimming (determing current memory level, trim command to
16771                    // send to process) since there can be an arbitrary number of stopping
16772                    // processes and they should soon all go into the cached state.
16773                    if (!r.finishing) {
16774                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16775                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16776                        }
16777                    }
16778                    app.cached = false;
16779                    app.empty = false;
16780                    foregroundActivities = true;
16781                } else {
16782                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16783                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16784                        app.adjType = "cch-act";
16785                    }
16786                }
16787            }
16788        }
16789
16790        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16791            if (app.foregroundServices) {
16792                // The user is aware of this app, so make it visible.
16793                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16794                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16795                app.cached = false;
16796                app.adjType = "fg-service";
16797                schedGroup = Process.THREAD_GROUP_DEFAULT;
16798            } else if (app.forcingToForeground != null) {
16799                // The user is aware of this app, so make it visible.
16800                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16801                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16802                app.cached = false;
16803                app.adjType = "force-fg";
16804                app.adjSource = app.forcingToForeground;
16805                schedGroup = Process.THREAD_GROUP_DEFAULT;
16806            }
16807        }
16808
16809        if (app == mHeavyWeightProcess) {
16810            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16811                // We don't want to kill the current heavy-weight process.
16812                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16813                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16814                app.cached = false;
16815                app.adjType = "heavy";
16816            }
16817            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16818                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16819            }
16820        }
16821
16822        if (app == mHomeProcess) {
16823            if (adj > ProcessList.HOME_APP_ADJ) {
16824                // This process is hosting what we currently consider to be the
16825                // home app, so we don't want to let it go into the background.
16826                adj = ProcessList.HOME_APP_ADJ;
16827                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16828                app.cached = false;
16829                app.adjType = "home";
16830            }
16831            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16832                procState = ActivityManager.PROCESS_STATE_HOME;
16833            }
16834        }
16835
16836        if (app == mPreviousProcess && app.activities.size() > 0) {
16837            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16838                // This was the previous process that showed UI to the user.
16839                // We want to try to keep it around more aggressively, to give
16840                // a good experience around switching between two apps.
16841                adj = ProcessList.PREVIOUS_APP_ADJ;
16842                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16843                app.cached = false;
16844                app.adjType = "previous";
16845            }
16846            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16847                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16848            }
16849        }
16850
16851        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16852                + " reason=" + app.adjType);
16853
16854        // By default, we use the computed adjustment.  It may be changed if
16855        // there are applications dependent on our services or providers, but
16856        // this gives us a baseline and makes sure we don't get into an
16857        // infinite recursion.
16858        app.adjSeq = mAdjSeq;
16859        app.curRawAdj = adj;
16860        app.hasStartedServices = false;
16861
16862        if (mBackupTarget != null && app == mBackupTarget.app) {
16863            // If possible we want to avoid killing apps while they're being backed up
16864            if (adj > ProcessList.BACKUP_APP_ADJ) {
16865                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16866                adj = ProcessList.BACKUP_APP_ADJ;
16867                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16868                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16869                }
16870                app.adjType = "backup";
16871                app.cached = false;
16872            }
16873            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16874                procState = ActivityManager.PROCESS_STATE_BACKUP;
16875            }
16876        }
16877
16878        boolean mayBeTop = false;
16879
16880        for (int is = app.services.size()-1;
16881                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16882                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16883                        || procState > ActivityManager.PROCESS_STATE_TOP);
16884                is--) {
16885            ServiceRecord s = app.services.valueAt(is);
16886            if (s.startRequested) {
16887                app.hasStartedServices = true;
16888                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16889                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16890                }
16891                if (app.hasShownUi && app != mHomeProcess) {
16892                    // If this process has shown some UI, let it immediately
16893                    // go to the LRU list because it may be pretty heavy with
16894                    // UI stuff.  We'll tag it with a label just to help
16895                    // debug and understand what is going on.
16896                    if (adj > ProcessList.SERVICE_ADJ) {
16897                        app.adjType = "cch-started-ui-services";
16898                    }
16899                } else {
16900                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16901                        // This service has seen some activity within
16902                        // recent memory, so we will keep its process ahead
16903                        // of the background processes.
16904                        if (adj > ProcessList.SERVICE_ADJ) {
16905                            adj = ProcessList.SERVICE_ADJ;
16906                            app.adjType = "started-services";
16907                            app.cached = false;
16908                        }
16909                    }
16910                    // If we have let the service slide into the background
16911                    // state, still have some text describing what it is doing
16912                    // even though the service no longer has an impact.
16913                    if (adj > ProcessList.SERVICE_ADJ) {
16914                        app.adjType = "cch-started-services";
16915                    }
16916                }
16917            }
16918            for (int conni = s.connections.size()-1;
16919                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16920                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16921                            || procState > ActivityManager.PROCESS_STATE_TOP);
16922                    conni--) {
16923                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16924                for (int i = 0;
16925                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16926                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16927                                || procState > ActivityManager.PROCESS_STATE_TOP);
16928                        i++) {
16929                    // XXX should compute this based on the max of
16930                    // all connected clients.
16931                    ConnectionRecord cr = clist.get(i);
16932                    if (cr.binding.client == app) {
16933                        // Binding to ourself is not interesting.
16934                        continue;
16935                    }
16936                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16937                        ProcessRecord client = cr.binding.client;
16938                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16939                                TOP_APP, doingAll, now);
16940                        int clientProcState = client.curProcState;
16941                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16942                            // If the other app is cached for any reason, for purposes here
16943                            // we are going to consider it empty.  The specific cached state
16944                            // doesn't propagate except under certain conditions.
16945                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16946                        }
16947                        String adjType = null;
16948                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16949                            // Not doing bind OOM management, so treat
16950                            // this guy more like a started service.
16951                            if (app.hasShownUi && app != mHomeProcess) {
16952                                // If this process has shown some UI, let it immediately
16953                                // go to the LRU list because it may be pretty heavy with
16954                                // UI stuff.  We'll tag it with a label just to help
16955                                // debug and understand what is going on.
16956                                if (adj > clientAdj) {
16957                                    adjType = "cch-bound-ui-services";
16958                                }
16959                                app.cached = false;
16960                                clientAdj = adj;
16961                                clientProcState = procState;
16962                            } else {
16963                                if (now >= (s.lastActivity
16964                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16965                                    // This service has not seen activity within
16966                                    // recent memory, so allow it to drop to the
16967                                    // LRU list if there is no other reason to keep
16968                                    // it around.  We'll also tag it with a label just
16969                                    // to help debug and undertand what is going on.
16970                                    if (adj > clientAdj) {
16971                                        adjType = "cch-bound-services";
16972                                    }
16973                                    clientAdj = adj;
16974                                }
16975                            }
16976                        }
16977                        if (adj > clientAdj) {
16978                            // If this process has recently shown UI, and
16979                            // the process that is binding to it is less
16980                            // important than being visible, then we don't
16981                            // care about the binding as much as we care
16982                            // about letting this process get into the LRU
16983                            // list to be killed and restarted if needed for
16984                            // memory.
16985                            if (app.hasShownUi && app != mHomeProcess
16986                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16987                                adjType = "cch-bound-ui-services";
16988                            } else {
16989                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16990                                        |Context.BIND_IMPORTANT)) != 0) {
16991                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16992                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16993                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16994                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16995                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16996                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16997                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16998                                    adj = clientAdj;
16999                                } else {
17000                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17001                                        adj = ProcessList.VISIBLE_APP_ADJ;
17002                                    }
17003                                }
17004                                if (!client.cached) {
17005                                    app.cached = false;
17006                                }
17007                                adjType = "service";
17008                            }
17009                        }
17010                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17011                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17012                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17013                            }
17014                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17015                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17016                                    // Special handling of clients who are in the top state.
17017                                    // We *may* want to consider this process to be in the
17018                                    // top state as well, but only if there is not another
17019                                    // reason for it to be running.  Being on the top is a
17020                                    // special state, meaning you are specifically running
17021                                    // for the current top app.  If the process is already
17022                                    // running in the background for some other reason, it
17023                                    // is more important to continue considering it to be
17024                                    // in the background state.
17025                                    mayBeTop = true;
17026                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17027                                } else {
17028                                    // Special handling for above-top states (persistent
17029                                    // processes).  These should not bring the current process
17030                                    // into the top state, since they are not on top.  Instead
17031                                    // give them the best state after that.
17032                                    clientProcState =
17033                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17034                                }
17035                            }
17036                        } else {
17037                            if (clientProcState <
17038                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17039                                clientProcState =
17040                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17041                            }
17042                        }
17043                        if (procState > clientProcState) {
17044                            procState = clientProcState;
17045                        }
17046                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17047                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17048                            app.pendingUiClean = true;
17049                        }
17050                        if (adjType != null) {
17051                            app.adjType = adjType;
17052                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17053                                    .REASON_SERVICE_IN_USE;
17054                            app.adjSource = cr.binding.client;
17055                            app.adjSourceProcState = clientProcState;
17056                            app.adjTarget = s.name;
17057                        }
17058                    }
17059                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17060                        app.treatLikeActivity = true;
17061                    }
17062                    final ActivityRecord a = cr.activity;
17063                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17064                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17065                                (a.visible || a.state == ActivityState.RESUMED
17066                                 || a.state == ActivityState.PAUSING)) {
17067                            adj = ProcessList.FOREGROUND_APP_ADJ;
17068                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17069                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17070                            }
17071                            app.cached = false;
17072                            app.adjType = "service";
17073                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17074                                    .REASON_SERVICE_IN_USE;
17075                            app.adjSource = a;
17076                            app.adjSourceProcState = procState;
17077                            app.adjTarget = s.name;
17078                        }
17079                    }
17080                }
17081            }
17082        }
17083
17084        for (int provi = app.pubProviders.size()-1;
17085                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17086                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17087                        || procState > ActivityManager.PROCESS_STATE_TOP);
17088                provi--) {
17089            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17090            for (int i = cpr.connections.size()-1;
17091                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17092                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17093                            || procState > ActivityManager.PROCESS_STATE_TOP);
17094                    i--) {
17095                ContentProviderConnection conn = cpr.connections.get(i);
17096                ProcessRecord client = conn.client;
17097                if (client == app) {
17098                    // Being our own client is not interesting.
17099                    continue;
17100                }
17101                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17102                int clientProcState = client.curProcState;
17103                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17104                    // If the other app is cached for any reason, for purposes here
17105                    // we are going to consider it empty.
17106                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17107                }
17108                if (adj > clientAdj) {
17109                    if (app.hasShownUi && app != mHomeProcess
17110                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17111                        app.adjType = "cch-ui-provider";
17112                    } else {
17113                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17114                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17115                        app.adjType = "provider";
17116                    }
17117                    app.cached &= client.cached;
17118                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17119                            .REASON_PROVIDER_IN_USE;
17120                    app.adjSource = client;
17121                    app.adjSourceProcState = clientProcState;
17122                    app.adjTarget = cpr.name;
17123                }
17124                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17125                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17126                        // Special handling of clients who are in the top state.
17127                        // We *may* want to consider this process to be in the
17128                        // top state as well, but only if there is not another
17129                        // reason for it to be running.  Being on the top is a
17130                        // special state, meaning you are specifically running
17131                        // for the current top app.  If the process is already
17132                        // running in the background for some other reason, it
17133                        // is more important to continue considering it to be
17134                        // in the background state.
17135                        mayBeTop = true;
17136                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17137                    } else {
17138                        // Special handling for above-top states (persistent
17139                        // processes).  These should not bring the current process
17140                        // into the top state, since they are not on top.  Instead
17141                        // give them the best state after that.
17142                        clientProcState =
17143                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17144                    }
17145                }
17146                if (procState > clientProcState) {
17147                    procState = clientProcState;
17148                }
17149                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17150                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17151                }
17152            }
17153            // If the provider has external (non-framework) process
17154            // dependencies, ensure that its adjustment is at least
17155            // FOREGROUND_APP_ADJ.
17156            if (cpr.hasExternalProcessHandles()) {
17157                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17158                    adj = ProcessList.FOREGROUND_APP_ADJ;
17159                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17160                    app.cached = false;
17161                    app.adjType = "provider";
17162                    app.adjTarget = cpr.name;
17163                }
17164                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17165                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17166                }
17167            }
17168        }
17169
17170        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17171            // A client of one of our services or providers is in the top state.  We
17172            // *may* want to be in the top state, but not if we are already running in
17173            // the background for some other reason.  For the decision here, we are going
17174            // to pick out a few specific states that we want to remain in when a client
17175            // is top (states that tend to be longer-term) and otherwise allow it to go
17176            // to the top state.
17177            switch (procState) {
17178                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17179                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17180                case ActivityManager.PROCESS_STATE_SERVICE:
17181                    // These all are longer-term states, so pull them up to the top
17182                    // of the background states, but not all the way to the top state.
17183                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17184                    break;
17185                default:
17186                    // Otherwise, top is a better choice, so take it.
17187                    procState = ActivityManager.PROCESS_STATE_TOP;
17188                    break;
17189            }
17190        }
17191
17192        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17193            if (app.hasClientActivities) {
17194                // This is a cached process, but with client activities.  Mark it so.
17195                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17196                app.adjType = "cch-client-act";
17197            } else if (app.treatLikeActivity) {
17198                // This is a cached process, but somebody wants us to treat it like it has
17199                // an activity, okay!
17200                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17201                app.adjType = "cch-as-act";
17202            }
17203        }
17204
17205        if (adj == ProcessList.SERVICE_ADJ) {
17206            if (doingAll) {
17207                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17208                mNewNumServiceProcs++;
17209                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17210                if (!app.serviceb) {
17211                    // This service isn't far enough down on the LRU list to
17212                    // normally be a B service, but if we are low on RAM and it
17213                    // is large we want to force it down since we would prefer to
17214                    // keep launcher over it.
17215                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17216                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17217                        app.serviceHighRam = true;
17218                        app.serviceb = true;
17219                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17220                    } else {
17221                        mNewNumAServiceProcs++;
17222                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17223                    }
17224                } else {
17225                    app.serviceHighRam = false;
17226                }
17227            }
17228            if (app.serviceb) {
17229                adj = ProcessList.SERVICE_B_ADJ;
17230            }
17231        }
17232
17233        app.curRawAdj = adj;
17234
17235        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17236        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17237        if (adj > app.maxAdj) {
17238            adj = app.maxAdj;
17239            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17240                schedGroup = Process.THREAD_GROUP_DEFAULT;
17241            }
17242        }
17243
17244        // Do final modification to adj.  Everything we do between here and applying
17245        // the final setAdj must be done in this function, because we will also use
17246        // it when computing the final cached adj later.  Note that we don't need to
17247        // worry about this for max adj above, since max adj will always be used to
17248        // keep it out of the cached vaues.
17249        app.curAdj = app.modifyRawOomAdj(adj);
17250        app.curSchedGroup = schedGroup;
17251        app.curProcState = procState;
17252        app.foregroundActivities = foregroundActivities;
17253
17254        return app.curRawAdj;
17255    }
17256
17257    /**
17258     * Schedule PSS collection of a process.
17259     */
17260    void requestPssLocked(ProcessRecord proc, int procState) {
17261        if (mPendingPssProcesses.contains(proc)) {
17262            return;
17263        }
17264        if (mPendingPssProcesses.size() == 0) {
17265            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17266        }
17267        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17268        proc.pssProcState = procState;
17269        mPendingPssProcesses.add(proc);
17270    }
17271
17272    /**
17273     * Schedule PSS collection of all processes.
17274     */
17275    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17276        if (!always) {
17277            if (now < (mLastFullPssTime +
17278                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17279                return;
17280            }
17281        }
17282        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17283        mLastFullPssTime = now;
17284        mFullPssPending = true;
17285        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17286        mPendingPssProcesses.clear();
17287        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17288            ProcessRecord app = mLruProcesses.get(i);
17289            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17290                app.pssProcState = app.setProcState;
17291                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17292                        isSleeping(), now);
17293                mPendingPssProcesses.add(app);
17294            }
17295        }
17296        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17297    }
17298
17299    /**
17300     * Ask a given process to GC right now.
17301     */
17302    final void performAppGcLocked(ProcessRecord app) {
17303        try {
17304            app.lastRequestedGc = SystemClock.uptimeMillis();
17305            if (app.thread != null) {
17306                if (app.reportLowMemory) {
17307                    app.reportLowMemory = false;
17308                    app.thread.scheduleLowMemory();
17309                } else {
17310                    app.thread.processInBackground();
17311                }
17312            }
17313        } catch (Exception e) {
17314            // whatever.
17315        }
17316    }
17317
17318    /**
17319     * Returns true if things are idle enough to perform GCs.
17320     */
17321    private final boolean canGcNowLocked() {
17322        boolean processingBroadcasts = false;
17323        for (BroadcastQueue q : mBroadcastQueues) {
17324            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17325                processingBroadcasts = true;
17326            }
17327        }
17328        return !processingBroadcasts
17329                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17330    }
17331
17332    /**
17333     * Perform GCs on all processes that are waiting for it, but only
17334     * if things are idle.
17335     */
17336    final void performAppGcsLocked() {
17337        final int N = mProcessesToGc.size();
17338        if (N <= 0) {
17339            return;
17340        }
17341        if (canGcNowLocked()) {
17342            while (mProcessesToGc.size() > 0) {
17343                ProcessRecord proc = mProcessesToGc.remove(0);
17344                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17345                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17346                            <= SystemClock.uptimeMillis()) {
17347                        // To avoid spamming the system, we will GC processes one
17348                        // at a time, waiting a few seconds between each.
17349                        performAppGcLocked(proc);
17350                        scheduleAppGcsLocked();
17351                        return;
17352                    } else {
17353                        // It hasn't been long enough since we last GCed this
17354                        // process...  put it in the list to wait for its time.
17355                        addProcessToGcListLocked(proc);
17356                        break;
17357                    }
17358                }
17359            }
17360
17361            scheduleAppGcsLocked();
17362        }
17363    }
17364
17365    /**
17366     * If all looks good, perform GCs on all processes waiting for them.
17367     */
17368    final void performAppGcsIfAppropriateLocked() {
17369        if (canGcNowLocked()) {
17370            performAppGcsLocked();
17371            return;
17372        }
17373        // Still not idle, wait some more.
17374        scheduleAppGcsLocked();
17375    }
17376
17377    /**
17378     * Schedule the execution of all pending app GCs.
17379     */
17380    final void scheduleAppGcsLocked() {
17381        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17382
17383        if (mProcessesToGc.size() > 0) {
17384            // Schedule a GC for the time to the next process.
17385            ProcessRecord proc = mProcessesToGc.get(0);
17386            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17387
17388            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17389            long now = SystemClock.uptimeMillis();
17390            if (when < (now+GC_TIMEOUT)) {
17391                when = now + GC_TIMEOUT;
17392            }
17393            mHandler.sendMessageAtTime(msg, when);
17394        }
17395    }
17396
17397    /**
17398     * Add a process to the array of processes waiting to be GCed.  Keeps the
17399     * list in sorted order by the last GC time.  The process can't already be
17400     * on the list.
17401     */
17402    final void addProcessToGcListLocked(ProcessRecord proc) {
17403        boolean added = false;
17404        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17405            if (mProcessesToGc.get(i).lastRequestedGc <
17406                    proc.lastRequestedGc) {
17407                added = true;
17408                mProcessesToGc.add(i+1, proc);
17409                break;
17410            }
17411        }
17412        if (!added) {
17413            mProcessesToGc.add(0, proc);
17414        }
17415    }
17416
17417    /**
17418     * Set up to ask a process to GC itself.  This will either do it
17419     * immediately, or put it on the list of processes to gc the next
17420     * time things are idle.
17421     */
17422    final void scheduleAppGcLocked(ProcessRecord app) {
17423        long now = SystemClock.uptimeMillis();
17424        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17425            return;
17426        }
17427        if (!mProcessesToGc.contains(app)) {
17428            addProcessToGcListLocked(app);
17429            scheduleAppGcsLocked();
17430        }
17431    }
17432
17433    final void checkExcessivePowerUsageLocked(boolean doKills) {
17434        updateCpuStatsNow();
17435
17436        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17437        boolean doWakeKills = doKills;
17438        boolean doCpuKills = doKills;
17439        if (mLastPowerCheckRealtime == 0) {
17440            doWakeKills = false;
17441        }
17442        if (mLastPowerCheckUptime == 0) {
17443            doCpuKills = false;
17444        }
17445        if (stats.isScreenOn()) {
17446            doWakeKills = false;
17447        }
17448        final long curRealtime = SystemClock.elapsedRealtime();
17449        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17450        final long curUptime = SystemClock.uptimeMillis();
17451        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17452        mLastPowerCheckRealtime = curRealtime;
17453        mLastPowerCheckUptime = curUptime;
17454        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17455            doWakeKills = false;
17456        }
17457        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17458            doCpuKills = false;
17459        }
17460        int i = mLruProcesses.size();
17461        while (i > 0) {
17462            i--;
17463            ProcessRecord app = mLruProcesses.get(i);
17464            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17465                long wtime;
17466                synchronized (stats) {
17467                    wtime = stats.getProcessWakeTime(app.info.uid,
17468                            app.pid, curRealtime);
17469                }
17470                long wtimeUsed = wtime - app.lastWakeTime;
17471                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17472                if (DEBUG_POWER) {
17473                    StringBuilder sb = new StringBuilder(128);
17474                    sb.append("Wake for ");
17475                    app.toShortString(sb);
17476                    sb.append(": over ");
17477                    TimeUtils.formatDuration(realtimeSince, sb);
17478                    sb.append(" used ");
17479                    TimeUtils.formatDuration(wtimeUsed, sb);
17480                    sb.append(" (");
17481                    sb.append((wtimeUsed*100)/realtimeSince);
17482                    sb.append("%)");
17483                    Slog.i(TAG, sb.toString());
17484                    sb.setLength(0);
17485                    sb.append("CPU for ");
17486                    app.toShortString(sb);
17487                    sb.append(": over ");
17488                    TimeUtils.formatDuration(uptimeSince, sb);
17489                    sb.append(" used ");
17490                    TimeUtils.formatDuration(cputimeUsed, sb);
17491                    sb.append(" (");
17492                    sb.append((cputimeUsed*100)/uptimeSince);
17493                    sb.append("%)");
17494                    Slog.i(TAG, sb.toString());
17495                }
17496                // If a process has held a wake lock for more
17497                // than 50% of the time during this period,
17498                // that sounds bad.  Kill!
17499                if (doWakeKills && realtimeSince > 0
17500                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17501                    synchronized (stats) {
17502                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17503                                realtimeSince, wtimeUsed);
17504                    }
17505                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17506                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17507                } else if (doCpuKills && uptimeSince > 0
17508                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17509                    synchronized (stats) {
17510                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17511                                uptimeSince, cputimeUsed);
17512                    }
17513                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17514                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17515                } else {
17516                    app.lastWakeTime = wtime;
17517                    app.lastCpuTime = app.curCpuTime;
17518                }
17519            }
17520        }
17521    }
17522
17523    private final boolean applyOomAdjLocked(ProcessRecord app,
17524            ProcessRecord TOP_APP, boolean doingAll, long now) {
17525        boolean success = true;
17526
17527        if (app.curRawAdj != app.setRawAdj) {
17528            app.setRawAdj = app.curRawAdj;
17529        }
17530
17531        int changes = 0;
17532
17533        if (app.curAdj != app.setAdj) {
17534            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17535            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17536                TAG, "Set " + app.pid + " " + app.processName +
17537                " adj " + app.curAdj + ": " + app.adjType);
17538            app.setAdj = app.curAdj;
17539        }
17540
17541        if (app.setSchedGroup != app.curSchedGroup) {
17542            app.setSchedGroup = app.curSchedGroup;
17543            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17544                    "Setting process group of " + app.processName
17545                    + " to " + app.curSchedGroup);
17546            if (app.waitingToKill != null &&
17547                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17548                app.kill(app.waitingToKill, true);
17549                success = false;
17550            } else {
17551                if (true) {
17552                    long oldId = Binder.clearCallingIdentity();
17553                    try {
17554                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17555                    } catch (Exception e) {
17556                        Slog.w(TAG, "Failed setting process group of " + app.pid
17557                                + " to " + app.curSchedGroup);
17558                        e.printStackTrace();
17559                    } finally {
17560                        Binder.restoreCallingIdentity(oldId);
17561                    }
17562                } else {
17563                    if (app.thread != null) {
17564                        try {
17565                            app.thread.setSchedulingGroup(app.curSchedGroup);
17566                        } catch (RemoteException e) {
17567                        }
17568                    }
17569                }
17570                Process.setSwappiness(app.pid,
17571                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17572            }
17573        }
17574        if (app.repForegroundActivities != app.foregroundActivities) {
17575            app.repForegroundActivities = app.foregroundActivities;
17576            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17577        }
17578        if (app.repProcState != app.curProcState) {
17579            app.repProcState = app.curProcState;
17580            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17581            if (app.thread != null) {
17582                try {
17583                    if (false) {
17584                        //RuntimeException h = new RuntimeException("here");
17585                        Slog.i(TAG, "Sending new process state " + app.repProcState
17586                                + " to " + app /*, h*/);
17587                    }
17588                    app.thread.setProcessState(app.repProcState);
17589                } catch (RemoteException e) {
17590                }
17591            }
17592        }
17593        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17594                app.setProcState)) {
17595            app.lastStateTime = now;
17596            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17597                    isSleeping(), now);
17598            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17599                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17600                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17601                    + (app.nextPssTime-now) + ": " + app);
17602        } else {
17603            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17604                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17605                requestPssLocked(app, app.setProcState);
17606                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17607                        isSleeping(), now);
17608            } else if (false && DEBUG_PSS) {
17609                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17610            }
17611        }
17612        if (app.setProcState != app.curProcState) {
17613            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17614                    "Proc state change of " + app.processName
17615                    + " to " + app.curProcState);
17616            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17617            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17618            if (setImportant && !curImportant) {
17619                // This app is no longer something we consider important enough to allow to
17620                // use arbitrary amounts of battery power.  Note
17621                // its current wake lock time to later know to kill it if
17622                // it is not behaving well.
17623                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17624                synchronized (stats) {
17625                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17626                            app.pid, SystemClock.elapsedRealtime());
17627                }
17628                app.lastCpuTime = app.curCpuTime;
17629
17630            }
17631            app.setProcState = app.curProcState;
17632            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17633                app.notCachedSinceIdle = false;
17634            }
17635            if (!doingAll) {
17636                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17637            } else {
17638                app.procStateChanged = true;
17639            }
17640        }
17641
17642        if (changes != 0) {
17643            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17644            int i = mPendingProcessChanges.size()-1;
17645            ProcessChangeItem item = null;
17646            while (i >= 0) {
17647                item = mPendingProcessChanges.get(i);
17648                if (item.pid == app.pid) {
17649                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17650                    break;
17651                }
17652                i--;
17653            }
17654            if (i < 0) {
17655                // No existing item in pending changes; need a new one.
17656                final int NA = mAvailProcessChanges.size();
17657                if (NA > 0) {
17658                    item = mAvailProcessChanges.remove(NA-1);
17659                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17660                } else {
17661                    item = new ProcessChangeItem();
17662                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17663                }
17664                item.changes = 0;
17665                item.pid = app.pid;
17666                item.uid = app.info.uid;
17667                if (mPendingProcessChanges.size() == 0) {
17668                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17669                            "*** Enqueueing dispatch processes changed!");
17670                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17671                }
17672                mPendingProcessChanges.add(item);
17673            }
17674            item.changes |= changes;
17675            item.processState = app.repProcState;
17676            item.foregroundActivities = app.repForegroundActivities;
17677            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17678                    + Integer.toHexString(System.identityHashCode(item))
17679                    + " " + app.toShortString() + ": changes=" + item.changes
17680                    + " procState=" + item.processState
17681                    + " foreground=" + item.foregroundActivities
17682                    + " type=" + app.adjType + " source=" + app.adjSource
17683                    + " target=" + app.adjTarget);
17684        }
17685
17686        return success;
17687    }
17688
17689    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17690        if (proc.thread != null) {
17691            if (proc.baseProcessTracker != null) {
17692                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17693            }
17694            if (proc.repProcState >= 0) {
17695                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17696                        proc.repProcState);
17697            }
17698        }
17699    }
17700
17701    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17702            ProcessRecord TOP_APP, boolean doingAll, long now) {
17703        if (app.thread == null) {
17704            return false;
17705        }
17706
17707        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17708
17709        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17710    }
17711
17712    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17713            boolean oomAdj) {
17714        if (isForeground != proc.foregroundServices) {
17715            proc.foregroundServices = isForeground;
17716            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17717                    proc.info.uid);
17718            if (isForeground) {
17719                if (curProcs == null) {
17720                    curProcs = new ArrayList<ProcessRecord>();
17721                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17722                }
17723                if (!curProcs.contains(proc)) {
17724                    curProcs.add(proc);
17725                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17726                            proc.info.packageName, proc.info.uid);
17727                }
17728            } else {
17729                if (curProcs != null) {
17730                    if (curProcs.remove(proc)) {
17731                        mBatteryStatsService.noteEvent(
17732                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17733                                proc.info.packageName, proc.info.uid);
17734                        if (curProcs.size() <= 0) {
17735                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17736                        }
17737                    }
17738                }
17739            }
17740            if (oomAdj) {
17741                updateOomAdjLocked();
17742            }
17743        }
17744    }
17745
17746    private final ActivityRecord resumedAppLocked() {
17747        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17748        String pkg;
17749        int uid;
17750        if (act != null) {
17751            pkg = act.packageName;
17752            uid = act.info.applicationInfo.uid;
17753        } else {
17754            pkg = null;
17755            uid = -1;
17756        }
17757        // Has the UID or resumed package name changed?
17758        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17759                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17760            if (mCurResumedPackage != null) {
17761                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17762                        mCurResumedPackage, mCurResumedUid);
17763            }
17764            mCurResumedPackage = pkg;
17765            mCurResumedUid = uid;
17766            if (mCurResumedPackage != null) {
17767                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17768                        mCurResumedPackage, mCurResumedUid);
17769            }
17770        }
17771        return act;
17772    }
17773
17774    final boolean updateOomAdjLocked(ProcessRecord app) {
17775        final ActivityRecord TOP_ACT = resumedAppLocked();
17776        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17777        final boolean wasCached = app.cached;
17778
17779        mAdjSeq++;
17780
17781        // This is the desired cached adjusment we want to tell it to use.
17782        // If our app is currently cached, we know it, and that is it.  Otherwise,
17783        // we don't know it yet, and it needs to now be cached we will then
17784        // need to do a complete oom adj.
17785        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17786                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17787        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17788                SystemClock.uptimeMillis());
17789        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17790            // Changed to/from cached state, so apps after it in the LRU
17791            // list may also be changed.
17792            updateOomAdjLocked();
17793        }
17794        return success;
17795    }
17796
17797    final void updateOomAdjLocked() {
17798        final ActivityRecord TOP_ACT = resumedAppLocked();
17799        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17800        final long now = SystemClock.uptimeMillis();
17801        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17802        final int N = mLruProcesses.size();
17803
17804        if (false) {
17805            RuntimeException e = new RuntimeException();
17806            e.fillInStackTrace();
17807            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17808        }
17809
17810        mAdjSeq++;
17811        mNewNumServiceProcs = 0;
17812        mNewNumAServiceProcs = 0;
17813
17814        final int emptyProcessLimit;
17815        final int cachedProcessLimit;
17816        if (mProcessLimit <= 0) {
17817            emptyProcessLimit = cachedProcessLimit = 0;
17818        } else if (mProcessLimit == 1) {
17819            emptyProcessLimit = 1;
17820            cachedProcessLimit = 0;
17821        } else {
17822            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17823            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17824        }
17825
17826        // Let's determine how many processes we have running vs.
17827        // how many slots we have for background processes; we may want
17828        // to put multiple processes in a slot of there are enough of
17829        // them.
17830        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17831                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17832        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17833        if (numEmptyProcs > cachedProcessLimit) {
17834            // If there are more empty processes than our limit on cached
17835            // processes, then use the cached process limit for the factor.
17836            // This ensures that the really old empty processes get pushed
17837            // down to the bottom, so if we are running low on memory we will
17838            // have a better chance at keeping around more cached processes
17839            // instead of a gazillion empty processes.
17840            numEmptyProcs = cachedProcessLimit;
17841        }
17842        int emptyFactor = numEmptyProcs/numSlots;
17843        if (emptyFactor < 1) emptyFactor = 1;
17844        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17845        if (cachedFactor < 1) cachedFactor = 1;
17846        int stepCached = 0;
17847        int stepEmpty = 0;
17848        int numCached = 0;
17849        int numEmpty = 0;
17850        int numTrimming = 0;
17851
17852        mNumNonCachedProcs = 0;
17853        mNumCachedHiddenProcs = 0;
17854
17855        // First update the OOM adjustment for each of the
17856        // application processes based on their current state.
17857        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17858        int nextCachedAdj = curCachedAdj+1;
17859        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17860        int nextEmptyAdj = curEmptyAdj+2;
17861        for (int i=N-1; i>=0; i--) {
17862            ProcessRecord app = mLruProcesses.get(i);
17863            if (!app.killedByAm && app.thread != null) {
17864                app.procStateChanged = false;
17865                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17866
17867                // If we haven't yet assigned the final cached adj
17868                // to the process, do that now.
17869                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17870                    switch (app.curProcState) {
17871                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17872                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17873                            // This process is a cached process holding activities...
17874                            // assign it the next cached value for that type, and then
17875                            // step that cached level.
17876                            app.curRawAdj = curCachedAdj;
17877                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17878                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17879                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17880                                    + ")");
17881                            if (curCachedAdj != nextCachedAdj) {
17882                                stepCached++;
17883                                if (stepCached >= cachedFactor) {
17884                                    stepCached = 0;
17885                                    curCachedAdj = nextCachedAdj;
17886                                    nextCachedAdj += 2;
17887                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17888                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17889                                    }
17890                                }
17891                            }
17892                            break;
17893                        default:
17894                            // For everything else, assign next empty cached process
17895                            // level and bump that up.  Note that this means that
17896                            // long-running services that have dropped down to the
17897                            // cached level will be treated as empty (since their process
17898                            // state is still as a service), which is what we want.
17899                            app.curRawAdj = curEmptyAdj;
17900                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17901                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17902                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17903                                    + ")");
17904                            if (curEmptyAdj != nextEmptyAdj) {
17905                                stepEmpty++;
17906                                if (stepEmpty >= emptyFactor) {
17907                                    stepEmpty = 0;
17908                                    curEmptyAdj = nextEmptyAdj;
17909                                    nextEmptyAdj += 2;
17910                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17911                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17912                                    }
17913                                }
17914                            }
17915                            break;
17916                    }
17917                }
17918
17919                applyOomAdjLocked(app, TOP_APP, true, now);
17920
17921                // Count the number of process types.
17922                switch (app.curProcState) {
17923                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17924                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17925                        mNumCachedHiddenProcs++;
17926                        numCached++;
17927                        if (numCached > cachedProcessLimit) {
17928                            app.kill("cached #" + numCached, true);
17929                        }
17930                        break;
17931                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17932                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17933                                && app.lastActivityTime < oldTime) {
17934                            app.kill("empty for "
17935                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17936                                    / 1000) + "s", true);
17937                        } else {
17938                            numEmpty++;
17939                            if (numEmpty > emptyProcessLimit) {
17940                                app.kill("empty #" + numEmpty, true);
17941                            }
17942                        }
17943                        break;
17944                    default:
17945                        mNumNonCachedProcs++;
17946                        break;
17947                }
17948
17949                if (app.isolated && app.services.size() <= 0) {
17950                    // If this is an isolated process, and there are no
17951                    // services running in it, then the process is no longer
17952                    // needed.  We agressively kill these because we can by
17953                    // definition not re-use the same process again, and it is
17954                    // good to avoid having whatever code was running in them
17955                    // left sitting around after no longer needed.
17956                    app.kill("isolated not needed", true);
17957                }
17958
17959                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17960                        && !app.killedByAm) {
17961                    numTrimming++;
17962                }
17963            }
17964        }
17965
17966        mNumServiceProcs = mNewNumServiceProcs;
17967
17968        // Now determine the memory trimming level of background processes.
17969        // Unfortunately we need to start at the back of the list to do this
17970        // properly.  We only do this if the number of background apps we
17971        // are managing to keep around is less than half the maximum we desire;
17972        // if we are keeping a good number around, we'll let them use whatever
17973        // memory they want.
17974        final int numCachedAndEmpty = numCached + numEmpty;
17975        int memFactor;
17976        if (numCached <= ProcessList.TRIM_CACHED_APPS
17977                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17978            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17979                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17980            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17981                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17982            } else {
17983                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17984            }
17985        } else {
17986            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17987        }
17988        // We always allow the memory level to go up (better).  We only allow it to go
17989        // down if we are in a state where that is allowed, *and* the total number of processes
17990        // has gone down since last time.
17991        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17992                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17993                + " last=" + mLastNumProcesses);
17994        if (memFactor > mLastMemoryLevel) {
17995            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17996                memFactor = mLastMemoryLevel;
17997                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17998            }
17999        }
18000        mLastMemoryLevel = memFactor;
18001        mLastNumProcesses = mLruProcesses.size();
18002        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18003        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18004        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18005            if (mLowRamStartTime == 0) {
18006                mLowRamStartTime = now;
18007            }
18008            int step = 0;
18009            int fgTrimLevel;
18010            switch (memFactor) {
18011                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18012                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18013                    break;
18014                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18015                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18016                    break;
18017                default:
18018                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18019                    break;
18020            }
18021            int factor = numTrimming/3;
18022            int minFactor = 2;
18023            if (mHomeProcess != null) minFactor++;
18024            if (mPreviousProcess != null) minFactor++;
18025            if (factor < minFactor) factor = minFactor;
18026            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18027            for (int i=N-1; i>=0; i--) {
18028                ProcessRecord app = mLruProcesses.get(i);
18029                if (allChanged || app.procStateChanged) {
18030                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18031                    app.procStateChanged = false;
18032                }
18033                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18034                        && !app.killedByAm) {
18035                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18036                        try {
18037                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18038                                    "Trimming memory of " + app.processName
18039                                    + " to " + curLevel);
18040                            app.thread.scheduleTrimMemory(curLevel);
18041                        } catch (RemoteException e) {
18042                        }
18043                        if (false) {
18044                            // For now we won't do this; our memory trimming seems
18045                            // to be good enough at this point that destroying
18046                            // activities causes more harm than good.
18047                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18048                                    && app != mHomeProcess && app != mPreviousProcess) {
18049                                // Need to do this on its own message because the stack may not
18050                                // be in a consistent state at this point.
18051                                // For these apps we will also finish their activities
18052                                // to help them free memory.
18053                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18054                            }
18055                        }
18056                    }
18057                    app.trimMemoryLevel = curLevel;
18058                    step++;
18059                    if (step >= factor) {
18060                        step = 0;
18061                        switch (curLevel) {
18062                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18063                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18064                                break;
18065                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18066                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18067                                break;
18068                        }
18069                    }
18070                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18071                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18072                            && app.thread != null) {
18073                        try {
18074                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18075                                    "Trimming memory of heavy-weight " + app.processName
18076                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18077                            app.thread.scheduleTrimMemory(
18078                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18079                        } catch (RemoteException e) {
18080                        }
18081                    }
18082                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18083                } else {
18084                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18085                            || app.systemNoUi) && app.pendingUiClean) {
18086                        // If this application is now in the background and it
18087                        // had done UI, then give it the special trim level to
18088                        // have it free UI resources.
18089                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18090                        if (app.trimMemoryLevel < level && app.thread != null) {
18091                            try {
18092                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18093                                        "Trimming memory of bg-ui " + app.processName
18094                                        + " to " + level);
18095                                app.thread.scheduleTrimMemory(level);
18096                            } catch (RemoteException e) {
18097                            }
18098                        }
18099                        app.pendingUiClean = false;
18100                    }
18101                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18102                        try {
18103                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18104                                    "Trimming memory of fg " + app.processName
18105                                    + " to " + fgTrimLevel);
18106                            app.thread.scheduleTrimMemory(fgTrimLevel);
18107                        } catch (RemoteException e) {
18108                        }
18109                    }
18110                    app.trimMemoryLevel = fgTrimLevel;
18111                }
18112            }
18113        } else {
18114            if (mLowRamStartTime != 0) {
18115                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18116                mLowRamStartTime = 0;
18117            }
18118            for (int i=N-1; i>=0; i--) {
18119                ProcessRecord app = mLruProcesses.get(i);
18120                if (allChanged || app.procStateChanged) {
18121                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18122                    app.procStateChanged = false;
18123                }
18124                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18125                        || app.systemNoUi) && app.pendingUiClean) {
18126                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18127                            && app.thread != null) {
18128                        try {
18129                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18130                                    "Trimming memory of ui hidden " + app.processName
18131                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18132                            app.thread.scheduleTrimMemory(
18133                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18134                        } catch (RemoteException e) {
18135                        }
18136                    }
18137                    app.pendingUiClean = false;
18138                }
18139                app.trimMemoryLevel = 0;
18140            }
18141        }
18142
18143        if (mAlwaysFinishActivities) {
18144            // Need to do this on its own message because the stack may not
18145            // be in a consistent state at this point.
18146            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18147        }
18148
18149        if (allChanged) {
18150            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18151        }
18152
18153        if (mProcessStats.shouldWriteNowLocked(now)) {
18154            mHandler.post(new Runnable() {
18155                @Override public void run() {
18156                    synchronized (ActivityManagerService.this) {
18157                        mProcessStats.writeStateAsyncLocked();
18158                    }
18159                }
18160            });
18161        }
18162
18163        if (DEBUG_OOM_ADJ) {
18164            if (false) {
18165                RuntimeException here = new RuntimeException("here");
18166                here.fillInStackTrace();
18167                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18168            } else {
18169                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18170            }
18171        }
18172    }
18173
18174    final void trimApplications() {
18175        synchronized (this) {
18176            int i;
18177
18178            // First remove any unused application processes whose package
18179            // has been removed.
18180            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18181                final ProcessRecord app = mRemovedProcesses.get(i);
18182                if (app.activities.size() == 0
18183                        && app.curReceiver == null && app.services.size() == 0) {
18184                    Slog.i(
18185                        TAG, "Exiting empty application process "
18186                        + app.processName + " ("
18187                        + (app.thread != null ? app.thread.asBinder() : null)
18188                        + ")\n");
18189                    if (app.pid > 0 && app.pid != MY_PID) {
18190                        app.kill("empty", false);
18191                    } else {
18192                        try {
18193                            app.thread.scheduleExit();
18194                        } catch (Exception e) {
18195                            // Ignore exceptions.
18196                        }
18197                    }
18198                    cleanUpApplicationRecordLocked(app, false, true, -1);
18199                    mRemovedProcesses.remove(i);
18200
18201                    if (app.persistent) {
18202                        addAppLocked(app.info, false, null /* ABI override */);
18203                    }
18204                }
18205            }
18206
18207            // Now update the oom adj for all processes.
18208            updateOomAdjLocked();
18209        }
18210    }
18211
18212    /** This method sends the specified signal to each of the persistent apps */
18213    public void signalPersistentProcesses(int sig) throws RemoteException {
18214        if (sig != Process.SIGNAL_USR1) {
18215            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18216        }
18217
18218        synchronized (this) {
18219            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18220                    != PackageManager.PERMISSION_GRANTED) {
18221                throw new SecurityException("Requires permission "
18222                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18223            }
18224
18225            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18226                ProcessRecord r = mLruProcesses.get(i);
18227                if (r.thread != null && r.persistent) {
18228                    Process.sendSignal(r.pid, sig);
18229                }
18230            }
18231        }
18232    }
18233
18234    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18235        if (proc == null || proc == mProfileProc) {
18236            proc = mProfileProc;
18237            profileType = mProfileType;
18238            clearProfilerLocked();
18239        }
18240        if (proc == null) {
18241            return;
18242        }
18243        try {
18244            proc.thread.profilerControl(false, null, profileType);
18245        } catch (RemoteException e) {
18246            throw new IllegalStateException("Process disappeared");
18247        }
18248    }
18249
18250    private void clearProfilerLocked() {
18251        if (mProfileFd != null) {
18252            try {
18253                mProfileFd.close();
18254            } catch (IOException e) {
18255            }
18256        }
18257        mProfileApp = null;
18258        mProfileProc = null;
18259        mProfileFile = null;
18260        mProfileType = 0;
18261        mAutoStopProfiler = false;
18262        mSamplingInterval = 0;
18263    }
18264
18265    public boolean profileControl(String process, int userId, boolean start,
18266            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18267
18268        try {
18269            synchronized (this) {
18270                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18271                // its own permission.
18272                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18273                        != PackageManager.PERMISSION_GRANTED) {
18274                    throw new SecurityException("Requires permission "
18275                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18276                }
18277
18278                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18279                    throw new IllegalArgumentException("null profile info or fd");
18280                }
18281
18282                ProcessRecord proc = null;
18283                if (process != null) {
18284                    proc = findProcessLocked(process, userId, "profileControl");
18285                }
18286
18287                if (start && (proc == null || proc.thread == null)) {
18288                    throw new IllegalArgumentException("Unknown process: " + process);
18289                }
18290
18291                if (start) {
18292                    stopProfilerLocked(null, 0);
18293                    setProfileApp(proc.info, proc.processName, profilerInfo);
18294                    mProfileProc = proc;
18295                    mProfileType = profileType;
18296                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18297                    try {
18298                        fd = fd.dup();
18299                    } catch (IOException e) {
18300                        fd = null;
18301                    }
18302                    profilerInfo.profileFd = fd;
18303                    proc.thread.profilerControl(start, profilerInfo, profileType);
18304                    fd = null;
18305                    mProfileFd = null;
18306                } else {
18307                    stopProfilerLocked(proc, profileType);
18308                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18309                        try {
18310                            profilerInfo.profileFd.close();
18311                        } catch (IOException e) {
18312                        }
18313                    }
18314                }
18315
18316                return true;
18317            }
18318        } catch (RemoteException e) {
18319            throw new IllegalStateException("Process disappeared");
18320        } finally {
18321            if (profilerInfo != null && profilerInfo.profileFd != null) {
18322                try {
18323                    profilerInfo.profileFd.close();
18324                } catch (IOException e) {
18325                }
18326            }
18327        }
18328    }
18329
18330    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18331        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18332                userId, true, ALLOW_FULL_ONLY, callName, null);
18333        ProcessRecord proc = null;
18334        try {
18335            int pid = Integer.parseInt(process);
18336            synchronized (mPidsSelfLocked) {
18337                proc = mPidsSelfLocked.get(pid);
18338            }
18339        } catch (NumberFormatException e) {
18340        }
18341
18342        if (proc == null) {
18343            ArrayMap<String, SparseArray<ProcessRecord>> all
18344                    = mProcessNames.getMap();
18345            SparseArray<ProcessRecord> procs = all.get(process);
18346            if (procs != null && procs.size() > 0) {
18347                proc = procs.valueAt(0);
18348                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18349                    for (int i=1; i<procs.size(); i++) {
18350                        ProcessRecord thisProc = procs.valueAt(i);
18351                        if (thisProc.userId == userId) {
18352                            proc = thisProc;
18353                            break;
18354                        }
18355                    }
18356                }
18357            }
18358        }
18359
18360        return proc;
18361    }
18362
18363    public boolean dumpHeap(String process, int userId, boolean managed,
18364            String path, ParcelFileDescriptor fd) throws RemoteException {
18365
18366        try {
18367            synchronized (this) {
18368                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18369                // its own permission (same as profileControl).
18370                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18371                        != PackageManager.PERMISSION_GRANTED) {
18372                    throw new SecurityException("Requires permission "
18373                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18374                }
18375
18376                if (fd == null) {
18377                    throw new IllegalArgumentException("null fd");
18378                }
18379
18380                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18381                if (proc == null || proc.thread == null) {
18382                    throw new IllegalArgumentException("Unknown process: " + process);
18383                }
18384
18385                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18386                if (!isDebuggable) {
18387                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18388                        throw new SecurityException("Process not debuggable: " + proc);
18389                    }
18390                }
18391
18392                proc.thread.dumpHeap(managed, path, fd);
18393                fd = null;
18394                return true;
18395            }
18396        } catch (RemoteException e) {
18397            throw new IllegalStateException("Process disappeared");
18398        } finally {
18399            if (fd != null) {
18400                try {
18401                    fd.close();
18402                } catch (IOException e) {
18403                }
18404            }
18405        }
18406    }
18407
18408    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18409    public void monitor() {
18410        synchronized (this) { }
18411    }
18412
18413    void onCoreSettingsChange(Bundle settings) {
18414        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18415            ProcessRecord processRecord = mLruProcesses.get(i);
18416            try {
18417                if (processRecord.thread != null) {
18418                    processRecord.thread.setCoreSettings(settings);
18419                }
18420            } catch (RemoteException re) {
18421                /* ignore */
18422            }
18423        }
18424    }
18425
18426    // Multi-user methods
18427
18428    /**
18429     * Start user, if its not already running, but don't bring it to foreground.
18430     */
18431    @Override
18432    public boolean startUserInBackground(final int userId) {
18433        return startUser(userId, /* foreground */ false);
18434    }
18435
18436    /**
18437     * Start user, if its not already running, and bring it to foreground.
18438     */
18439    boolean startUserInForeground(final int userId, Dialog dlg) {
18440        boolean result = startUser(userId, /* foreground */ true);
18441        dlg.dismiss();
18442        return result;
18443    }
18444
18445    /**
18446     * Refreshes the list of users related to the current user when either a
18447     * user switch happens or when a new related user is started in the
18448     * background.
18449     */
18450    private void updateCurrentProfileIdsLocked() {
18451        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18452                mCurrentUserId, false /* enabledOnly */);
18453        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18454        for (int i = 0; i < currentProfileIds.length; i++) {
18455            currentProfileIds[i] = profiles.get(i).id;
18456        }
18457        mCurrentProfileIds = currentProfileIds;
18458
18459        synchronized (mUserProfileGroupIdsSelfLocked) {
18460            mUserProfileGroupIdsSelfLocked.clear();
18461            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18462            for (int i = 0; i < users.size(); i++) {
18463                UserInfo user = users.get(i);
18464                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18465                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18466                }
18467            }
18468        }
18469    }
18470
18471    private Set getProfileIdsLocked(int userId) {
18472        Set userIds = new HashSet<Integer>();
18473        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18474                userId, false /* enabledOnly */);
18475        for (UserInfo user : profiles) {
18476            userIds.add(Integer.valueOf(user.id));
18477        }
18478        return userIds;
18479    }
18480
18481    @Override
18482    public boolean switchUser(final int userId) {
18483        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18484        String userName;
18485        synchronized (this) {
18486            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18487            if (userInfo == null) {
18488                Slog.w(TAG, "No user info for user #" + userId);
18489                return false;
18490            }
18491            if (userInfo.isManagedProfile()) {
18492                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18493                return false;
18494            }
18495            userName = userInfo.name;
18496            mTargetUserId = userId;
18497        }
18498        mHandler.removeMessages(START_USER_SWITCH_MSG);
18499        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18500        return true;
18501    }
18502
18503    private void showUserSwitchDialog(int userId, String userName) {
18504        // The dialog will show and then initiate the user switch by calling startUserInForeground
18505        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18506                true /* above system */);
18507        d.show();
18508    }
18509
18510    private boolean startUser(final int userId, final boolean foreground) {
18511        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18512                != PackageManager.PERMISSION_GRANTED) {
18513            String msg = "Permission Denial: switchUser() from pid="
18514                    + Binder.getCallingPid()
18515                    + ", uid=" + Binder.getCallingUid()
18516                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18517            Slog.w(TAG, msg);
18518            throw new SecurityException(msg);
18519        }
18520
18521        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18522
18523        final long ident = Binder.clearCallingIdentity();
18524        try {
18525            synchronized (this) {
18526                final int oldUserId = mCurrentUserId;
18527                if (oldUserId == userId) {
18528                    return true;
18529                }
18530
18531                mStackSupervisor.setLockTaskModeLocked(null, false);
18532
18533                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18534                if (userInfo == null) {
18535                    Slog.w(TAG, "No user info for user #" + userId);
18536                    return false;
18537                }
18538                if (foreground && userInfo.isManagedProfile()) {
18539                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18540                    return false;
18541                }
18542
18543                if (foreground) {
18544                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18545                            R.anim.screen_user_enter);
18546                }
18547
18548                boolean needStart = false;
18549
18550                // If the user we are switching to is not currently started, then
18551                // we need to start it now.
18552                if (mStartedUsers.get(userId) == null) {
18553                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18554                    updateStartedUserArrayLocked();
18555                    needStart = true;
18556                }
18557
18558                final Integer userIdInt = Integer.valueOf(userId);
18559                mUserLru.remove(userIdInt);
18560                mUserLru.add(userIdInt);
18561
18562                if (foreground) {
18563                    mCurrentUserId = userId;
18564                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18565                    updateCurrentProfileIdsLocked();
18566                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18567                    // Once the internal notion of the active user has switched, we lock the device
18568                    // with the option to show the user switcher on the keyguard.
18569                    mWindowManager.lockNow(null);
18570                } else {
18571                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18572                    updateCurrentProfileIdsLocked();
18573                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18574                    mUserLru.remove(currentUserIdInt);
18575                    mUserLru.add(currentUserIdInt);
18576                }
18577
18578                final UserStartedState uss = mStartedUsers.get(userId);
18579
18580                // Make sure user is in the started state.  If it is currently
18581                // stopping, we need to knock that off.
18582                if (uss.mState == UserStartedState.STATE_STOPPING) {
18583                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18584                    // so we can just fairly silently bring the user back from
18585                    // the almost-dead.
18586                    uss.mState = UserStartedState.STATE_RUNNING;
18587                    updateStartedUserArrayLocked();
18588                    needStart = true;
18589                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18590                    // This means ACTION_SHUTDOWN has been sent, so we will
18591                    // need to treat this as a new boot of the user.
18592                    uss.mState = UserStartedState.STATE_BOOTING;
18593                    updateStartedUserArrayLocked();
18594                    needStart = true;
18595                }
18596
18597                if (uss.mState == UserStartedState.STATE_BOOTING) {
18598                    // Booting up a new user, need to tell system services about it.
18599                    // Note that this is on the same handler as scheduling of broadcasts,
18600                    // which is important because it needs to go first.
18601                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18602                }
18603
18604                if (foreground) {
18605                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18606                            oldUserId));
18607                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18608                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18609                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18610                            oldUserId, userId, uss));
18611                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18612                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18613                }
18614
18615                if (needStart) {
18616                    // Send USER_STARTED broadcast
18617                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18618                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18619                            | Intent.FLAG_RECEIVER_FOREGROUND);
18620                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18621                    broadcastIntentLocked(null, null, intent,
18622                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18623                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18624                }
18625
18626                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18627                    if (userId != UserHandle.USER_OWNER) {
18628                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18629                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18630                        broadcastIntentLocked(null, null, intent, null,
18631                                new IIntentReceiver.Stub() {
18632                                    public void performReceive(Intent intent, int resultCode,
18633                                            String data, Bundle extras, boolean ordered,
18634                                            boolean sticky, int sendingUser) {
18635                                        onUserInitialized(uss, foreground, oldUserId, userId);
18636                                    }
18637                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18638                                true, false, MY_PID, Process.SYSTEM_UID,
18639                                userId);
18640                        uss.initializing = true;
18641                    } else {
18642                        getUserManagerLocked().makeInitialized(userInfo.id);
18643                    }
18644                }
18645
18646                if (foreground) {
18647                    if (!uss.initializing) {
18648                        moveUserToForeground(uss, oldUserId, userId);
18649                    }
18650                } else {
18651                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18652                }
18653
18654                if (needStart) {
18655                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18656                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18657                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18658                    broadcastIntentLocked(null, null, intent,
18659                            null, new IIntentReceiver.Stub() {
18660                                @Override
18661                                public void performReceive(Intent intent, int resultCode, String data,
18662                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18663                                        throws RemoteException {
18664                                }
18665                            }, 0, null, null,
18666                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18667                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18668                }
18669            }
18670        } finally {
18671            Binder.restoreCallingIdentity(ident);
18672        }
18673
18674        return true;
18675    }
18676
18677    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18678        long ident = Binder.clearCallingIdentity();
18679        try {
18680            Intent intent;
18681            if (oldUserId >= 0) {
18682                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18683                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18684                int count = profiles.size();
18685                for (int i = 0; i < count; i++) {
18686                    int profileUserId = profiles.get(i).id;
18687                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18688                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18689                            | Intent.FLAG_RECEIVER_FOREGROUND);
18690                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18691                    broadcastIntentLocked(null, null, intent,
18692                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18693                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18694                }
18695            }
18696            if (newUserId >= 0) {
18697                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18698                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18699                int count = profiles.size();
18700                for (int i = 0; i < count; i++) {
18701                    int profileUserId = profiles.get(i).id;
18702                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18703                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18704                            | Intent.FLAG_RECEIVER_FOREGROUND);
18705                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18706                    broadcastIntentLocked(null, null, intent,
18707                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18708                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18709                }
18710                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18711                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18712                        | Intent.FLAG_RECEIVER_FOREGROUND);
18713                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18714                broadcastIntentLocked(null, null, intent,
18715                        null, null, 0, null, null,
18716                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18717                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18718            }
18719        } finally {
18720            Binder.restoreCallingIdentity(ident);
18721        }
18722    }
18723
18724    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18725            final int newUserId) {
18726        final int N = mUserSwitchObservers.beginBroadcast();
18727        if (N > 0) {
18728            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18729                int mCount = 0;
18730                @Override
18731                public void sendResult(Bundle data) throws RemoteException {
18732                    synchronized (ActivityManagerService.this) {
18733                        if (mCurUserSwitchCallback == this) {
18734                            mCount++;
18735                            if (mCount == N) {
18736                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18737                            }
18738                        }
18739                    }
18740                }
18741            };
18742            synchronized (this) {
18743                uss.switching = true;
18744                mCurUserSwitchCallback = callback;
18745            }
18746            for (int i=0; i<N; i++) {
18747                try {
18748                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18749                            newUserId, callback);
18750                } catch (RemoteException e) {
18751                }
18752            }
18753        } else {
18754            synchronized (this) {
18755                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18756            }
18757        }
18758        mUserSwitchObservers.finishBroadcast();
18759    }
18760
18761    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18762        synchronized (this) {
18763            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18764            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18765        }
18766    }
18767
18768    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18769        mCurUserSwitchCallback = null;
18770        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18771        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18772                oldUserId, newUserId, uss));
18773    }
18774
18775    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18776        synchronized (this) {
18777            if (foreground) {
18778                moveUserToForeground(uss, oldUserId, newUserId);
18779            }
18780        }
18781
18782        completeSwitchAndInitalize(uss, newUserId, true, false);
18783    }
18784
18785    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18786        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18787        if (homeInFront) {
18788            startHomeActivityLocked(newUserId);
18789        } else {
18790            mStackSupervisor.resumeTopActivitiesLocked();
18791        }
18792        EventLogTags.writeAmSwitchUser(newUserId);
18793        getUserManagerLocked().userForeground(newUserId);
18794        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18795    }
18796
18797    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18798        completeSwitchAndInitalize(uss, newUserId, false, true);
18799    }
18800
18801    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18802            boolean clearInitializing, boolean clearSwitching) {
18803        boolean unfrozen = false;
18804        synchronized (this) {
18805            if (clearInitializing) {
18806                uss.initializing = false;
18807                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18808            }
18809            if (clearSwitching) {
18810                uss.switching = false;
18811            }
18812            if (!uss.switching && !uss.initializing) {
18813                mWindowManager.stopFreezingScreen();
18814                unfrozen = true;
18815            }
18816        }
18817        if (unfrozen) {
18818            final int N = mUserSwitchObservers.beginBroadcast();
18819            for (int i=0; i<N; i++) {
18820                try {
18821                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18822                } catch (RemoteException e) {
18823                }
18824            }
18825            mUserSwitchObservers.finishBroadcast();
18826        }
18827    }
18828
18829    void scheduleStartProfilesLocked() {
18830        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18831            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18832                    DateUtils.SECOND_IN_MILLIS);
18833        }
18834    }
18835
18836    void startProfilesLocked() {
18837        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18838        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18839                mCurrentUserId, false /* enabledOnly */);
18840        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18841        for (UserInfo user : profiles) {
18842            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18843                    && user.id != mCurrentUserId) {
18844                toStart.add(user);
18845            }
18846        }
18847        final int n = toStart.size();
18848        int i = 0;
18849        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18850            startUserInBackground(toStart.get(i).id);
18851        }
18852        if (i < n) {
18853            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18854        }
18855    }
18856
18857    void finishUserBoot(UserStartedState uss) {
18858        synchronized (this) {
18859            if (uss.mState == UserStartedState.STATE_BOOTING
18860                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18861                uss.mState = UserStartedState.STATE_RUNNING;
18862                final int userId = uss.mHandle.getIdentifier();
18863                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18864                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18865                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18866                broadcastIntentLocked(null, null, intent,
18867                        null, null, 0, null, null,
18868                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18869                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18870            }
18871        }
18872    }
18873
18874    void finishUserSwitch(UserStartedState uss) {
18875        synchronized (this) {
18876            finishUserBoot(uss);
18877
18878            startProfilesLocked();
18879
18880            int num = mUserLru.size();
18881            int i = 0;
18882            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18883                Integer oldUserId = mUserLru.get(i);
18884                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18885                if (oldUss == null) {
18886                    // Shouldn't happen, but be sane if it does.
18887                    mUserLru.remove(i);
18888                    num--;
18889                    continue;
18890                }
18891                if (oldUss.mState == UserStartedState.STATE_STOPPING
18892                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18893                    // This user is already stopping, doesn't count.
18894                    num--;
18895                    i++;
18896                    continue;
18897                }
18898                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18899                    // Owner and current can't be stopped, but count as running.
18900                    i++;
18901                    continue;
18902                }
18903                // This is a user to be stopped.
18904                stopUserLocked(oldUserId, null);
18905                num--;
18906                i++;
18907            }
18908        }
18909    }
18910
18911    @Override
18912    public int stopUser(final int userId, final IStopUserCallback callback) {
18913        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18914                != PackageManager.PERMISSION_GRANTED) {
18915            String msg = "Permission Denial: switchUser() from pid="
18916                    + Binder.getCallingPid()
18917                    + ", uid=" + Binder.getCallingUid()
18918                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18919            Slog.w(TAG, msg);
18920            throw new SecurityException(msg);
18921        }
18922        if (userId <= 0) {
18923            throw new IllegalArgumentException("Can't stop primary user " + userId);
18924        }
18925        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18926        synchronized (this) {
18927            return stopUserLocked(userId, callback);
18928        }
18929    }
18930
18931    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18932        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18933        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18934            return ActivityManager.USER_OP_IS_CURRENT;
18935        }
18936
18937        final UserStartedState uss = mStartedUsers.get(userId);
18938        if (uss == null) {
18939            // User is not started, nothing to do...  but we do need to
18940            // callback if requested.
18941            if (callback != null) {
18942                mHandler.post(new Runnable() {
18943                    @Override
18944                    public void run() {
18945                        try {
18946                            callback.userStopped(userId);
18947                        } catch (RemoteException e) {
18948                        }
18949                    }
18950                });
18951            }
18952            return ActivityManager.USER_OP_SUCCESS;
18953        }
18954
18955        if (callback != null) {
18956            uss.mStopCallbacks.add(callback);
18957        }
18958
18959        if (uss.mState != UserStartedState.STATE_STOPPING
18960                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18961            uss.mState = UserStartedState.STATE_STOPPING;
18962            updateStartedUserArrayLocked();
18963
18964            long ident = Binder.clearCallingIdentity();
18965            try {
18966                // We are going to broadcast ACTION_USER_STOPPING and then
18967                // once that is done send a final ACTION_SHUTDOWN and then
18968                // stop the user.
18969                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18970                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18971                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18972                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18973                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18974                // This is the result receiver for the final shutdown broadcast.
18975                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18976                    @Override
18977                    public void performReceive(Intent intent, int resultCode, String data,
18978                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18979                        finishUserStop(uss);
18980                    }
18981                };
18982                // This is the result receiver for the initial stopping broadcast.
18983                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18984                    @Override
18985                    public void performReceive(Intent intent, int resultCode, String data,
18986                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18987                        // On to the next.
18988                        synchronized (ActivityManagerService.this) {
18989                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18990                                // Whoops, we are being started back up.  Abort, abort!
18991                                return;
18992                            }
18993                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18994                        }
18995                        mBatteryStatsService.noteEvent(
18996                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18997                                Integer.toString(userId), userId);
18998                        mSystemServiceManager.stopUser(userId);
18999                        broadcastIntentLocked(null, null, shutdownIntent,
19000                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19001                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19002                    }
19003                };
19004                // Kick things off.
19005                broadcastIntentLocked(null, null, stoppingIntent,
19006                        null, stoppingReceiver, 0, null, null,
19007                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19008                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19009            } finally {
19010                Binder.restoreCallingIdentity(ident);
19011            }
19012        }
19013
19014        return ActivityManager.USER_OP_SUCCESS;
19015    }
19016
19017    void finishUserStop(UserStartedState uss) {
19018        final int userId = uss.mHandle.getIdentifier();
19019        boolean stopped;
19020        ArrayList<IStopUserCallback> callbacks;
19021        synchronized (this) {
19022            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19023            if (mStartedUsers.get(userId) != uss) {
19024                stopped = false;
19025            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19026                stopped = false;
19027            } else {
19028                stopped = true;
19029                // User can no longer run.
19030                mStartedUsers.remove(userId);
19031                mUserLru.remove(Integer.valueOf(userId));
19032                updateStartedUserArrayLocked();
19033
19034                // Clean up all state and processes associated with the user.
19035                // Kill all the processes for the user.
19036                forceStopUserLocked(userId, "finish user");
19037            }
19038
19039            // Explicitly remove the old information in mRecentTasks.
19040            removeRecentTasksForUserLocked(userId);
19041        }
19042
19043        for (int i=0; i<callbacks.size(); i++) {
19044            try {
19045                if (stopped) callbacks.get(i).userStopped(userId);
19046                else callbacks.get(i).userStopAborted(userId);
19047            } catch (RemoteException e) {
19048            }
19049        }
19050
19051        if (stopped) {
19052            mSystemServiceManager.cleanupUser(userId);
19053            synchronized (this) {
19054                mStackSupervisor.removeUserLocked(userId);
19055            }
19056        }
19057    }
19058
19059    @Override
19060    public UserInfo getCurrentUser() {
19061        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19062                != PackageManager.PERMISSION_GRANTED) && (
19063                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19064                != PackageManager.PERMISSION_GRANTED)) {
19065            String msg = "Permission Denial: getCurrentUser() from pid="
19066                    + Binder.getCallingPid()
19067                    + ", uid=" + Binder.getCallingUid()
19068                    + " requires " + INTERACT_ACROSS_USERS;
19069            Slog.w(TAG, msg);
19070            throw new SecurityException(msg);
19071        }
19072        synchronized (this) {
19073            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19074            return getUserManagerLocked().getUserInfo(userId);
19075        }
19076    }
19077
19078    int getCurrentUserIdLocked() {
19079        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19080    }
19081
19082    @Override
19083    public boolean isUserRunning(int userId, boolean orStopped) {
19084        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19085                != PackageManager.PERMISSION_GRANTED) {
19086            String msg = "Permission Denial: isUserRunning() from pid="
19087                    + Binder.getCallingPid()
19088                    + ", uid=" + Binder.getCallingUid()
19089                    + " requires " + INTERACT_ACROSS_USERS;
19090            Slog.w(TAG, msg);
19091            throw new SecurityException(msg);
19092        }
19093        synchronized (this) {
19094            return isUserRunningLocked(userId, orStopped);
19095        }
19096    }
19097
19098    boolean isUserRunningLocked(int userId, boolean orStopped) {
19099        UserStartedState state = mStartedUsers.get(userId);
19100        if (state == null) {
19101            return false;
19102        }
19103        if (orStopped) {
19104            return true;
19105        }
19106        return state.mState != UserStartedState.STATE_STOPPING
19107                && state.mState != UserStartedState.STATE_SHUTDOWN;
19108    }
19109
19110    @Override
19111    public int[] getRunningUserIds() {
19112        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19113                != PackageManager.PERMISSION_GRANTED) {
19114            String msg = "Permission Denial: isUserRunning() from pid="
19115                    + Binder.getCallingPid()
19116                    + ", uid=" + Binder.getCallingUid()
19117                    + " requires " + INTERACT_ACROSS_USERS;
19118            Slog.w(TAG, msg);
19119            throw new SecurityException(msg);
19120        }
19121        synchronized (this) {
19122            return mStartedUserArray;
19123        }
19124    }
19125
19126    private void updateStartedUserArrayLocked() {
19127        int num = 0;
19128        for (int i=0; i<mStartedUsers.size();  i++) {
19129            UserStartedState uss = mStartedUsers.valueAt(i);
19130            // This list does not include stopping users.
19131            if (uss.mState != UserStartedState.STATE_STOPPING
19132                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19133                num++;
19134            }
19135        }
19136        mStartedUserArray = new int[num];
19137        num = 0;
19138        for (int i=0; i<mStartedUsers.size();  i++) {
19139            UserStartedState uss = mStartedUsers.valueAt(i);
19140            if (uss.mState != UserStartedState.STATE_STOPPING
19141                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19142                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19143                num++;
19144            }
19145        }
19146    }
19147
19148    @Override
19149    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19150        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19151                != PackageManager.PERMISSION_GRANTED) {
19152            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19153                    + Binder.getCallingPid()
19154                    + ", uid=" + Binder.getCallingUid()
19155                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19156            Slog.w(TAG, msg);
19157            throw new SecurityException(msg);
19158        }
19159
19160        mUserSwitchObservers.register(observer);
19161    }
19162
19163    @Override
19164    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19165        mUserSwitchObservers.unregister(observer);
19166    }
19167
19168    private boolean userExists(int userId) {
19169        if (userId == 0) {
19170            return true;
19171        }
19172        UserManagerService ums = getUserManagerLocked();
19173        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19174    }
19175
19176    int[] getUsersLocked() {
19177        UserManagerService ums = getUserManagerLocked();
19178        return ums != null ? ums.getUserIds() : new int[] { 0 };
19179    }
19180
19181    UserManagerService getUserManagerLocked() {
19182        if (mUserManager == null) {
19183            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19184            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19185        }
19186        return mUserManager;
19187    }
19188
19189    private int applyUserId(int uid, int userId) {
19190        return UserHandle.getUid(userId, uid);
19191    }
19192
19193    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19194        if (info == null) return null;
19195        ApplicationInfo newInfo = new ApplicationInfo(info);
19196        newInfo.uid = applyUserId(info.uid, userId);
19197        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19198                + info.packageName;
19199        return newInfo;
19200    }
19201
19202    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19203        if (aInfo == null
19204                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19205            return aInfo;
19206        }
19207
19208        ActivityInfo info = new ActivityInfo(aInfo);
19209        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19210        return info;
19211    }
19212
19213    private final class LocalService extends ActivityManagerInternal {
19214        @Override
19215        public void onWakefulnessChanged(int wakefulness) {
19216            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19217        }
19218
19219        @Override
19220        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19221                String processName, String abiOverride, int uid, Runnable crashHandler) {
19222            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19223                    processName, abiOverride, uid, crashHandler);
19224        }
19225    }
19226
19227    /**
19228     * An implementation of IAppTask, that allows an app to manage its own tasks via
19229     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19230     * only the process that calls getAppTasks() can call the AppTask methods.
19231     */
19232    class AppTaskImpl extends IAppTask.Stub {
19233        private int mTaskId;
19234        private int mCallingUid;
19235
19236        public AppTaskImpl(int taskId, int callingUid) {
19237            mTaskId = taskId;
19238            mCallingUid = callingUid;
19239        }
19240
19241        private void checkCaller() {
19242            if (mCallingUid != Binder.getCallingUid()) {
19243                throw new SecurityException("Caller " + mCallingUid
19244                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19245            }
19246        }
19247
19248        @Override
19249        public void finishAndRemoveTask() {
19250            checkCaller();
19251
19252            synchronized (ActivityManagerService.this) {
19253                long origId = Binder.clearCallingIdentity();
19254                try {
19255                    if (!removeTaskByIdLocked(mTaskId, false)) {
19256                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19257                    }
19258                } finally {
19259                    Binder.restoreCallingIdentity(origId);
19260                }
19261            }
19262        }
19263
19264        @Override
19265        public ActivityManager.RecentTaskInfo getTaskInfo() {
19266            checkCaller();
19267
19268            synchronized (ActivityManagerService.this) {
19269                long origId = Binder.clearCallingIdentity();
19270                try {
19271                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19272                    if (tr == null) {
19273                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19274                    }
19275                    return createRecentTaskInfoFromTaskRecord(tr);
19276                } finally {
19277                    Binder.restoreCallingIdentity(origId);
19278                }
19279            }
19280        }
19281
19282        @Override
19283        public void moveToFront() {
19284            checkCaller();
19285
19286            final TaskRecord tr;
19287            synchronized (ActivityManagerService.this) {
19288                tr = recentTaskForIdLocked(mTaskId);
19289                if (tr == null) {
19290                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19291                }
19292                if (tr.getRootActivity() != null) {
19293                    moveTaskToFrontLocked(tr.taskId, 0, null);
19294                    return;
19295                }
19296            }
19297
19298            startActivityFromRecentsInner(tr.taskId, null);
19299        }
19300
19301        @Override
19302        public int startActivity(IBinder whoThread, String callingPackage,
19303                Intent intent, String resolvedType, Bundle options) {
19304            checkCaller();
19305
19306            int callingUser = UserHandle.getCallingUserId();
19307            TaskRecord tr;
19308            IApplicationThread appThread;
19309            synchronized (ActivityManagerService.this) {
19310                tr = recentTaskForIdLocked(mTaskId);
19311                if (tr == null) {
19312                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19313                }
19314                appThread = ApplicationThreadNative.asInterface(whoThread);
19315                if (appThread == null) {
19316                    throw new IllegalArgumentException("Bad app thread " + appThread);
19317                }
19318            }
19319            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19320                    resolvedType, null, null, null, null, 0, 0, null, null,
19321                    null, options, callingUser, null, tr);
19322        }
19323
19324        @Override
19325        public void setExcludeFromRecents(boolean exclude) {
19326            checkCaller();
19327
19328            synchronized (ActivityManagerService.this) {
19329                long origId = Binder.clearCallingIdentity();
19330                try {
19331                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19332                    if (tr == null) {
19333                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19334                    }
19335                    Intent intent = tr.getBaseIntent();
19336                    if (exclude) {
19337                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19338                    } else {
19339                        intent.setFlags(intent.getFlags()
19340                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19341                    }
19342                } finally {
19343                    Binder.restoreCallingIdentity(origId);
19344                }
19345            }
19346        }
19347    }
19348}
19349