ActivityManagerService.java revision 0a41a578023fc3614f8888552b32fe9ea0d74eae
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.os.storage.IMountService;
52import android.os.storage.StorageManager;
53import android.service.voice.IVoiceInteractionSession;
54import android.util.ArrayMap;
55import android.util.ArraySet;
56import android.util.SparseIntArray;
57
58import com.android.internal.R;
59import com.android.internal.annotations.GuardedBy;
60import com.android.internal.app.IAppOpsService;
61import com.android.internal.app.IVoiceInteractor;
62import com.android.internal.app.ProcessMap;
63import com.android.internal.app.ProcessStats;
64import com.android.internal.os.BackgroundThread;
65import com.android.internal.os.BatteryStatsImpl;
66import com.android.internal.os.ProcessCpuTracker;
67import com.android.internal.os.TransferPipe;
68import com.android.internal.os.Zygote;
69import com.android.internal.util.FastPrintWriter;
70import com.android.internal.util.FastXmlSerializer;
71import com.android.internal.util.MemInfoReader;
72import com.android.internal.util.Preconditions;
73import com.android.server.AppOpsService;
74import com.android.server.AttributeCache;
75import com.android.server.IntentResolver;
76import com.android.server.LocalServices;
77import com.android.server.ServiceThread;
78import com.android.server.SystemService;
79import com.android.server.SystemServiceManager;
80import com.android.server.Watchdog;
81import com.android.server.am.ActivityStack.ActivityState;
82import com.android.server.firewall.IntentFirewall;
83import com.android.server.pm.Installer;
84import com.android.server.pm.UserManagerService;
85import com.android.server.statusbar.StatusBarManagerInternal;
86import com.android.server.wm.AppTransition;
87import com.android.server.wm.WindowManagerService;
88import com.google.android.collect.Lists;
89import com.google.android.collect.Maps;
90
91import libcore.io.IoUtils;
92
93import org.xmlpull.v1.XmlPullParser;
94import org.xmlpull.v1.XmlPullParserException;
95import org.xmlpull.v1.XmlSerializer;
96
97import android.app.Activity;
98import android.app.ActivityManager;
99import android.app.ActivityManager.RunningTaskInfo;
100import android.app.ActivityManager.StackInfo;
101import android.app.ActivityManagerInternal;
102import android.app.ActivityManagerNative;
103import android.app.ActivityOptions;
104import android.app.ActivityThread;
105import android.app.AlertDialog;
106import android.app.AppGlobals;
107import android.app.ApplicationErrorReport;
108import android.app.Dialog;
109import android.app.IActivityController;
110import android.app.IApplicationThread;
111import android.app.IInstrumentationWatcher;
112import android.app.INotificationManager;
113import android.app.IProcessObserver;
114import android.app.IServiceConnection;
115import android.app.IStopUserCallback;
116import android.app.IUiAutomationConnection;
117import android.app.IUserSwitchObserver;
118import android.app.Instrumentation;
119import android.app.Notification;
120import android.app.NotificationManager;
121import android.app.PendingIntent;
122import android.app.backup.IBackupManager;
123import android.content.ActivityNotFoundException;
124import android.content.BroadcastReceiver;
125import android.content.ClipData;
126import android.content.ComponentCallbacks2;
127import android.content.ComponentName;
128import android.content.ContentProvider;
129import android.content.ContentResolver;
130import android.content.Context;
131import android.content.DialogInterface;
132import android.content.IContentProvider;
133import android.content.IIntentReceiver;
134import android.content.IIntentSender;
135import android.content.Intent;
136import android.content.IntentFilter;
137import android.content.IntentSender;
138import android.content.pm.ActivityInfo;
139import android.content.pm.ApplicationInfo;
140import android.content.pm.ConfigurationInfo;
141import android.content.pm.IPackageDataObserver;
142import android.content.pm.IPackageManager;
143import android.content.pm.InstrumentationInfo;
144import android.content.pm.PackageInfo;
145import android.content.pm.PackageManager;
146import android.content.pm.ParceledListSlice;
147import android.content.pm.UserInfo;
148import android.content.pm.PackageManager.NameNotFoundException;
149import android.content.pm.PathPermission;
150import android.content.pm.ProviderInfo;
151import android.content.pm.ResolveInfo;
152import android.content.pm.ServiceInfo;
153import android.content.res.CompatibilityInfo;
154import android.content.res.Configuration;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.Binder;
159import android.os.Build;
160import android.os.Bundle;
161import android.os.Debug;
162import android.os.DropBoxManager;
163import android.os.Environment;
164import android.os.FactoryTest;
165import android.os.FileObserver;
166import android.os.FileUtils;
167import android.os.Handler;
168import android.os.IBinder;
169import android.os.IPermissionController;
170import android.os.IRemoteCallback;
171import android.os.IUserManager;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.Process;
177import android.os.RemoteCallbackList;
178import android.os.RemoteException;
179import android.os.SELinux;
180import android.os.ServiceManager;
181import android.os.StrictMode;
182import android.os.SystemClock;
183import android.os.SystemProperties;
184import android.os.UpdateLock;
185import android.os.UserHandle;
186import android.os.UserManager;
187import android.provider.Settings;
188import android.text.format.DateUtils;
189import android.text.format.Time;
190import android.util.AtomicFile;
191import android.util.EventLog;
192import android.util.Log;
193import android.util.Pair;
194import android.util.PrintWriterPrinter;
195import android.util.Slog;
196import android.util.SparseArray;
197import android.util.TimeUtils;
198import android.util.Xml;
199import android.view.Gravity;
200import android.view.LayoutInflater;
201import android.view.View;
202import android.view.WindowManager;
203
204import dalvik.system.VMRuntime;
205
206import java.io.BufferedInputStream;
207import java.io.BufferedOutputStream;
208import java.io.DataInputStream;
209import java.io.DataOutputStream;
210import java.io.File;
211import java.io.FileDescriptor;
212import java.io.FileInputStream;
213import java.io.FileNotFoundException;
214import java.io.FileOutputStream;
215import java.io.IOException;
216import java.io.InputStreamReader;
217import java.io.PrintWriter;
218import java.io.StringWriter;
219import java.lang.ref.WeakReference;
220import java.util.ArrayList;
221import java.util.Arrays;
222import java.util.Collections;
223import java.util.Comparator;
224import java.util.HashMap;
225import java.util.HashSet;
226import java.util.Iterator;
227import java.util.List;
228import java.util.Locale;
229import java.util.Map;
230import java.util.Set;
231import java.util.concurrent.atomic.AtomicBoolean;
232import java.util.concurrent.atomic.AtomicLong;
233
234public final class ActivityManagerService extends ActivityManagerNative
235        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
236
237    private static final String USER_DATA_DIR = "/data/user/";
238    // File that stores last updated system version and called preboot receivers
239    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
240
241    static final String TAG = "ActivityManager";
242    static final String TAG_MU = "ActivityManagerServiceMU";
243    static final boolean DEBUG = false;
244    static final boolean localLOGV = DEBUG;
245    static final boolean DEBUG_BACKUP = localLOGV || false;
246    static final boolean DEBUG_BROADCAST = localLOGV || false;
247    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
248    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
249    static final boolean DEBUG_CLEANUP = localLOGV || false;
250    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
251    static final boolean DEBUG_FOCUS = false;
252    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
253    static final boolean DEBUG_MU = localLOGV || false;
254    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
255    static final boolean DEBUG_LRU = localLOGV || false;
256    static final boolean DEBUG_PAUSE = localLOGV || false;
257    static final boolean DEBUG_POWER = localLOGV || false;
258    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
259    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
260    static final boolean DEBUG_PROCESSES = localLOGV || false;
261    static final boolean DEBUG_PROVIDER = localLOGV || false;
262    static final boolean DEBUG_RESULTS = localLOGV || false;
263    static final boolean DEBUG_SERVICE = localLOGV || false;
264    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
265    static final boolean DEBUG_STACK = localLOGV || false;
266    static final boolean DEBUG_SWITCH = localLOGV || false;
267    static final boolean DEBUG_TASKS = localLOGV || false;
268    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
269    static final boolean DEBUG_TRANSITION = localLOGV || false;
270    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
271    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
272    static final boolean DEBUG_VISBILITY = localLOGV || false;
273    static final boolean DEBUG_PSS = localLOGV || false;
274    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
275    static final boolean DEBUG_RECENTS = localLOGV || false;
276    static final boolean VALIDATE_TOKENS = false;
277    static final boolean SHOW_ACTIVITY_START_TIME = true;
278
279    // Control over CPU and battery monitoring.
280    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
281    static final boolean MONITOR_CPU_USAGE = true;
282    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
283    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
284    static final boolean MONITOR_THREAD_CPU_USAGE = false;
285
286    // The flags that are set for all calls we make to the package manager.
287    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
288
289    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
290
291    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
292
293    // Maximum number recent bitmaps to keep in memory.
294    static final int MAX_RECENT_BITMAPS = 5;
295
296    // Amount of time after a call to stopAppSwitches() during which we will
297    // prevent further untrusted switches from happening.
298    static final long APP_SWITCH_DELAY_TIME = 5*1000;
299
300    // How long we wait for a launched process to attach to the activity manager
301    // before we decide it's never going to come up for real.
302    static final int PROC_START_TIMEOUT = 10*1000;
303
304    // How long we wait for a launched process to attach to the activity manager
305    // before we decide it's never going to come up for real, when the process was
306    // started with a wrapper for instrumentation (such as Valgrind) because it
307    // could take much longer than usual.
308    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
309
310    // How long to wait after going idle before forcing apps to GC.
311    static final int GC_TIMEOUT = 5*1000;
312
313    // The minimum amount of time between successive GC requests for a process.
314    static final int GC_MIN_INTERVAL = 60*1000;
315
316    // The minimum amount of time between successive PSS requests for a process.
317    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
318
319    // The minimum amount of time between successive PSS requests for a process
320    // when the request is due to the memory state being lowered.
321    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
322
323    // The rate at which we check for apps using excessive power -- 15 mins.
324    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
325
326    // The minimum sample duration we will allow before deciding we have
327    // enough data on wake locks to start killing things.
328    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
329
330    // The minimum sample duration we will allow before deciding we have
331    // enough data on CPU usage to start killing things.
332    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
333
334    // How long we allow a receiver to run before giving up on it.
335    static final int BROADCAST_FG_TIMEOUT = 10*1000;
336    static final int BROADCAST_BG_TIMEOUT = 60*1000;
337
338    // How long we wait until we timeout on key dispatching.
339    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
340
341    // How long we wait until we timeout on key dispatching during instrumentation.
342    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
343
344    // Amount of time we wait for observers to handle a user switch before
345    // giving up on them and unfreezing the screen.
346    static final int USER_SWITCH_TIMEOUT = 2*1000;
347
348    // Maximum number of users we allow to be running at a time.
349    static final int MAX_RUNNING_USERS = 3;
350
351    // How long to wait in getAssistContextExtras for the activity and foreground services
352    // to respond with the result.
353    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
354
355    // Maximum number of persisted Uri grants a package is allowed
356    static final int MAX_PERSISTED_URI_GRANTS = 128;
357
358    static final int MY_PID = Process.myPid();
359
360    static final String[] EMPTY_STRING_ARRAY = new String[0];
361
362    // How many bytes to write into the dropbox log before truncating
363    static final int DROPBOX_MAX_SIZE = 256 * 1024;
364
365    // Access modes for handleIncomingUser.
366    static final int ALLOW_NON_FULL = 0;
367    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
368    static final int ALLOW_FULL_ONLY = 2;
369
370    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
371
372    /** All system services */
373    SystemServiceManager mSystemServiceManager;
374
375    private Installer mInstaller;
376
377    /** Run all ActivityStacks through this */
378    ActivityStackSupervisor mStackSupervisor;
379
380    public IntentFirewall mIntentFirewall;
381
382    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
383    // default actuion automatically.  Important for devices without direct input
384    // devices.
385    private boolean mShowDialogs = true;
386
387    BroadcastQueue mFgBroadcastQueue;
388    BroadcastQueue mBgBroadcastQueue;
389    // Convenient for easy iteration over the queues. Foreground is first
390    // so that dispatch of foreground broadcasts gets precedence.
391    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
392
393    BroadcastQueue broadcastQueueForIntent(Intent intent) {
394        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
395        if (DEBUG_BACKGROUND_BROADCAST) {
396            Slog.i(TAG, "Broadcast intent " + intent + " on "
397                    + (isFg ? "foreground" : "background")
398                    + " queue");
399        }
400        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
401    }
402
403    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
404        for (BroadcastQueue queue : mBroadcastQueues) {
405            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
406            if (r != null) {
407                return r;
408            }
409        }
410        return null;
411    }
412
413    /**
414     * Activity we have told the window manager to have key focus.
415     */
416    ActivityRecord mFocusedActivity = null;
417
418    /**
419     * List of intents that were used to start the most recent tasks.
420     */
421    ArrayList<TaskRecord> mRecentTasks;
422    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
423
424    /**
425     * For addAppTask: cached of the last activity component that was added.
426     */
427    ComponentName mLastAddedTaskComponent;
428
429    /**
430     * For addAppTask: cached of the last activity uid that was added.
431     */
432    int mLastAddedTaskUid;
433
434    /**
435     * For addAppTask: cached of the last ActivityInfo that was added.
436     */
437    ActivityInfo mLastAddedTaskActivity;
438
439    public class PendingAssistExtras extends Binder implements Runnable {
440        public final ActivityRecord activity;
441        public final Bundle extras;
442        public final Intent intent;
443        public final String hint;
444        public final int userHandle;
445        public boolean haveResult = false;
446        public Bundle result = null;
447        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
448                String _hint, int _userHandle) {
449            activity = _activity;
450            extras = _extras;
451            intent = _intent;
452            hint = _hint;
453            userHandle = _userHandle;
454        }
455        @Override
456        public void run() {
457            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
458            synchronized (this) {
459                haveResult = true;
460                notifyAll();
461            }
462        }
463    }
464
465    final ArrayList<PendingAssistExtras> mPendingAssistExtras
466            = new ArrayList<PendingAssistExtras>();
467
468    /**
469     * Process management.
470     */
471    final ProcessList mProcessList = new ProcessList();
472
473    /**
474     * All of the applications we currently have running organized by name.
475     * The keys are strings of the application package name (as
476     * returned by the package manager), and the keys are ApplicationRecord
477     * objects.
478     */
479    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
480
481    /**
482     * Tracking long-term execution of processes to look for abuse and other
483     * bad app behavior.
484     */
485    final ProcessStatsService mProcessStats;
486
487    /**
488     * The currently running isolated processes.
489     */
490    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
491
492    /**
493     * Counter for assigning isolated process uids, to avoid frequently reusing the
494     * same ones.
495     */
496    int mNextIsolatedProcessUid = 0;
497
498    /**
499     * The currently running heavy-weight process, if any.
500     */
501    ProcessRecord mHeavyWeightProcess = null;
502
503    /**
504     * The last time that various processes have crashed.
505     */
506    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
507
508    /**
509     * Information about a process that is currently marked as bad.
510     */
511    static final class BadProcessInfo {
512        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
513            this.time = time;
514            this.shortMsg = shortMsg;
515            this.longMsg = longMsg;
516            this.stack = stack;
517        }
518
519        final long time;
520        final String shortMsg;
521        final String longMsg;
522        final String stack;
523    }
524
525    /**
526     * Set of applications that we consider to be bad, and will reject
527     * incoming broadcasts from (which the user has no control over).
528     * Processes are added to this set when they have crashed twice within
529     * a minimum amount of time; they are removed from it when they are
530     * later restarted (hopefully due to some user action).  The value is the
531     * time it was added to the list.
532     */
533    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
534
535    /**
536     * All of the processes we currently have running organized by pid.
537     * The keys are the pid running the application.
538     *
539     * <p>NOTE: This object is protected by its own lock, NOT the global
540     * activity manager lock!
541     */
542    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
543
544    /**
545     * All of the processes that have been forced to be foreground.  The key
546     * is the pid of the caller who requested it (we hold a death
547     * link on it).
548     */
549    abstract class ForegroundToken implements IBinder.DeathRecipient {
550        int pid;
551        IBinder token;
552    }
553    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
554
555    /**
556     * List of records for processes that someone had tried to start before the
557     * system was ready.  We don't start them at that point, but ensure they
558     * are started by the time booting is complete.
559     */
560    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
561
562    /**
563     * List of persistent applications that are in the process
564     * of being started.
565     */
566    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
567
568    /**
569     * Processes that are being forcibly torn down.
570     */
571    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
572
573    /**
574     * List of running applications, sorted by recent usage.
575     * The first entry in the list is the least recently used.
576     */
577    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
578
579    /**
580     * Where in mLruProcesses that the processes hosting activities start.
581     */
582    int mLruProcessActivityStart = 0;
583
584    /**
585     * Where in mLruProcesses that the processes hosting services start.
586     * This is after (lower index) than mLruProcessesActivityStart.
587     */
588    int mLruProcessServiceStart = 0;
589
590    /**
591     * List of processes that should gc as soon as things are idle.
592     */
593    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
594
595    /**
596     * Processes we want to collect PSS data from.
597     */
598    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
599
600    /**
601     * Last time we requested PSS data of all processes.
602     */
603    long mLastFullPssTime = SystemClock.uptimeMillis();
604
605    /**
606     * If set, the next time we collect PSS data we should do a full collection
607     * with data from native processes and the kernel.
608     */
609    boolean mFullPssPending = false;
610
611    /**
612     * This is the process holding what we currently consider to be
613     * the "home" activity.
614     */
615    ProcessRecord mHomeProcess;
616
617    /**
618     * This is the process holding the activity the user last visited that
619     * is in a different process from the one they are currently in.
620     */
621    ProcessRecord mPreviousProcess;
622
623    /**
624     * The time at which the previous process was last visible.
625     */
626    long mPreviousProcessVisibleTime;
627
628    /**
629     * Which uses have been started, so are allowed to run code.
630     */
631    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
632
633    /**
634     * LRU list of history of current users.  Most recently current is at the end.
635     */
636    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
637
638    /**
639     * Constant array of the users that are currently started.
640     */
641    int[] mStartedUserArray = new int[] { 0 };
642
643    /**
644     * Registered observers of the user switching mechanics.
645     */
646    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
647            = new RemoteCallbackList<IUserSwitchObserver>();
648
649    /**
650     * Currently active user switch.
651     */
652    Object mCurUserSwitchCallback;
653
654    /**
655     * Packages that the user has asked to have run in screen size
656     * compatibility mode instead of filling the screen.
657     */
658    final CompatModePackages mCompatModePackages;
659
660    /**
661     * Set of IntentSenderRecord objects that are currently active.
662     */
663    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
664            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
665
666    /**
667     * Fingerprints (hashCode()) of stack traces that we've
668     * already logged DropBox entries for.  Guarded by itself.  If
669     * something (rogue user app) forces this over
670     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
671     */
672    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
673    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
674
675    /**
676     * Strict Mode background batched logging state.
677     *
678     * The string buffer is guarded by itself, and its lock is also
679     * used to determine if another batched write is already
680     * in-flight.
681     */
682    private final StringBuilder mStrictModeBuffer = new StringBuilder();
683
684    /**
685     * Keeps track of all IIntentReceivers that have been registered for
686     * broadcasts.  Hash keys are the receiver IBinder, hash value is
687     * a ReceiverList.
688     */
689    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
690            new HashMap<IBinder, ReceiverList>();
691
692    /**
693     * Resolver for broadcast intents to registered receivers.
694     * Holds BroadcastFilter (subclass of IntentFilter).
695     */
696    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
697            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
698        @Override
699        protected boolean allowFilterResult(
700                BroadcastFilter filter, List<BroadcastFilter> dest) {
701            IBinder target = filter.receiverList.receiver.asBinder();
702            for (int i=dest.size()-1; i>=0; i--) {
703                if (dest.get(i).receiverList.receiver.asBinder() == target) {
704                    return false;
705                }
706            }
707            return true;
708        }
709
710        @Override
711        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
712            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
713                    || userId == filter.owningUserId) {
714                return super.newResult(filter, match, userId);
715            }
716            return null;
717        }
718
719        @Override
720        protected BroadcastFilter[] newArray(int size) {
721            return new BroadcastFilter[size];
722        }
723
724        @Override
725        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
726            return packageName.equals(filter.packageName);
727        }
728    };
729
730    /**
731     * State of all active sticky broadcasts per user.  Keys are the action of the
732     * sticky Intent, values are an ArrayList of all broadcasted intents with
733     * that action (which should usually be one).  The SparseArray is keyed
734     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
735     * for stickies that are sent to all users.
736     */
737    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
738            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
739
740    final ActiveServices mServices;
741
742    /**
743     * Backup/restore process management
744     */
745    String mBackupAppName = null;
746    BackupRecord mBackupTarget = null;
747
748    final ProviderMap mProviderMap;
749
750    /**
751     * List of content providers who have clients waiting for them.  The
752     * application is currently being launched and the provider will be
753     * removed from this list once it is published.
754     */
755    final ArrayList<ContentProviderRecord> mLaunchingProviders
756            = new ArrayList<ContentProviderRecord>();
757
758    /**
759     * File storing persisted {@link #mGrantedUriPermissions}.
760     */
761    private final AtomicFile mGrantFile;
762
763    /** XML constants used in {@link #mGrantFile} */
764    private static final String TAG_URI_GRANTS = "uri-grants";
765    private static final String TAG_URI_GRANT = "uri-grant";
766    private static final String ATTR_USER_HANDLE = "userHandle";
767    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
768    private static final String ATTR_TARGET_USER_ID = "targetUserId";
769    private static final String ATTR_SOURCE_PKG = "sourcePkg";
770    private static final String ATTR_TARGET_PKG = "targetPkg";
771    private static final String ATTR_URI = "uri";
772    private static final String ATTR_MODE_FLAGS = "modeFlags";
773    private static final String ATTR_CREATED_TIME = "createdTime";
774    private static final String ATTR_PREFIX = "prefix";
775
776    /**
777     * Global set of specific {@link Uri} permissions that have been granted.
778     * This optimized lookup structure maps from {@link UriPermission#targetUid}
779     * to {@link UriPermission#uri} to {@link UriPermission}.
780     */
781    @GuardedBy("this")
782    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
783            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
784
785    public static class GrantUri {
786        public final int sourceUserId;
787        public final Uri uri;
788        public boolean prefix;
789
790        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
791            this.sourceUserId = sourceUserId;
792            this.uri = uri;
793            this.prefix = prefix;
794        }
795
796        @Override
797        public int hashCode() {
798            return toString().hashCode();
799        }
800
801        @Override
802        public boolean equals(Object o) {
803            if (o instanceof GrantUri) {
804                GrantUri other = (GrantUri) o;
805                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
806                        && prefix == other.prefix;
807            }
808            return false;
809        }
810
811        @Override
812        public String toString() {
813            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
814            if (prefix) result += " [prefix]";
815            return result;
816        }
817
818        public String toSafeString() {
819            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
820            if (prefix) result += " [prefix]";
821            return result;
822        }
823
824        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
825            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
826                    ContentProvider.getUriWithoutUserId(uri), false);
827        }
828    }
829
830    CoreSettingsObserver mCoreSettingsObserver;
831
832    /**
833     * Thread-local storage used to carry caller permissions over through
834     * indirect content-provider access.
835     */
836    private class Identity {
837        public int pid;
838        public int uid;
839
840        Identity(int _pid, int _uid) {
841            pid = _pid;
842            uid = _uid;
843        }
844    }
845
846    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
847
848    /**
849     * All information we have collected about the runtime performance of
850     * any user id that can impact battery performance.
851     */
852    final BatteryStatsService mBatteryStatsService;
853
854    /**
855     * Information about component usage
856     */
857    UsageStatsManagerInternal mUsageStatsService;
858
859    /**
860     * Information about and control over application operations
861     */
862    final AppOpsService mAppOpsService;
863
864    /**
865     * Save recent tasks information across reboots.
866     */
867    final TaskPersister mTaskPersister;
868
869    /**
870     * Current configuration information.  HistoryRecord objects are given
871     * a reference to this object to indicate which configuration they are
872     * currently running in, so this object must be kept immutable.
873     */
874    Configuration mConfiguration = new Configuration();
875
876    /**
877     * Current sequencing integer of the configuration, for skipping old
878     * configurations.
879     */
880    int mConfigurationSeq = 0;
881
882    /**
883     * Hardware-reported OpenGLES version.
884     */
885    final int GL_ES_VERSION;
886
887    /**
888     * List of initialization arguments to pass to all processes when binding applications to them.
889     * For example, references to the commonly used services.
890     */
891    HashMap<String, IBinder> mAppBindArgs;
892
893    /**
894     * Temporary to avoid allocations.  Protected by main lock.
895     */
896    final StringBuilder mStringBuilder = new StringBuilder(256);
897
898    /**
899     * Used to control how we initialize the service.
900     */
901    ComponentName mTopComponent;
902    String mTopAction = Intent.ACTION_MAIN;
903    String mTopData;
904    boolean mProcessesReady = false;
905    boolean mSystemReady = false;
906    boolean mBooting = false;
907    boolean mCallFinishBooting = false;
908    boolean mBootAnimationComplete = false;
909    boolean mWaitingUpdate = false;
910    boolean mDidUpdate = false;
911    boolean mOnBattery = false;
912    boolean mLaunchWarningShown = false;
913
914    Context mContext;
915
916    int mFactoryTest;
917
918    boolean mCheckedForSetup;
919
920    /**
921     * The time at which we will allow normal application switches again,
922     * after a call to {@link #stopAppSwitches()}.
923     */
924    long mAppSwitchesAllowedTime;
925
926    /**
927     * This is set to true after the first switch after mAppSwitchesAllowedTime
928     * is set; any switches after that will clear the time.
929     */
930    boolean mDidAppSwitch;
931
932    /**
933     * Last time (in realtime) at which we checked for power usage.
934     */
935    long mLastPowerCheckRealtime;
936
937    /**
938     * Last time (in uptime) at which we checked for power usage.
939     */
940    long mLastPowerCheckUptime;
941
942    /**
943     * Set while we are wanting to sleep, to prevent any
944     * activities from being started/resumed.
945     */
946    private boolean mSleeping = false;
947
948    /**
949     * Set while we are running a voice interaction.  This overrides
950     * sleeping while it is active.
951     */
952    private boolean mRunningVoice = false;
953
954    /**
955     * State of external calls telling us if the device is asleep.
956     */
957    private boolean mWentToSleep = false;
958
959    static final int LOCK_SCREEN_HIDDEN = 0;
960    static final int LOCK_SCREEN_LEAVING = 1;
961    static final int LOCK_SCREEN_SHOWN = 2;
962    /**
963     * State of external call telling us if the lock screen is shown.
964     */
965    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
966
967    /**
968     * Set if we are shutting down the system, similar to sleeping.
969     */
970    boolean mShuttingDown = false;
971
972    /**
973     * Current sequence id for oom_adj computation traversal.
974     */
975    int mAdjSeq = 0;
976
977    /**
978     * Current sequence id for process LRU updating.
979     */
980    int mLruSeq = 0;
981
982    /**
983     * Keep track of the non-cached/empty process we last found, to help
984     * determine how to distribute cached/empty processes next time.
985     */
986    int mNumNonCachedProcs = 0;
987
988    /**
989     * Keep track of the number of cached hidden procs, to balance oom adj
990     * distribution between those and empty procs.
991     */
992    int mNumCachedHiddenProcs = 0;
993
994    /**
995     * Keep track of the number of service processes we last found, to
996     * determine on the next iteration which should be B services.
997     */
998    int mNumServiceProcs = 0;
999    int mNewNumAServiceProcs = 0;
1000    int mNewNumServiceProcs = 0;
1001
1002    /**
1003     * Allow the current computed overall memory level of the system to go down?
1004     * This is set to false when we are killing processes for reasons other than
1005     * memory management, so that the now smaller process list will not be taken as
1006     * an indication that memory is tighter.
1007     */
1008    boolean mAllowLowerMemLevel = false;
1009
1010    /**
1011     * The last computed memory level, for holding when we are in a state that
1012     * processes are going away for other reasons.
1013     */
1014    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1015
1016    /**
1017     * The last total number of process we have, to determine if changes actually look
1018     * like a shrinking number of process due to lower RAM.
1019     */
1020    int mLastNumProcesses;
1021
1022    /**
1023     * The uptime of the last time we performed idle maintenance.
1024     */
1025    long mLastIdleTime = SystemClock.uptimeMillis();
1026
1027    /**
1028     * Total time spent with RAM that has been added in the past since the last idle time.
1029     */
1030    long mLowRamTimeSinceLastIdle = 0;
1031
1032    /**
1033     * If RAM is currently low, when that horrible situation started.
1034     */
1035    long mLowRamStartTime = 0;
1036
1037    /**
1038     * For reporting to battery stats the current top application.
1039     */
1040    private String mCurResumedPackage = null;
1041    private int mCurResumedUid = -1;
1042
1043    /**
1044     * For reporting to battery stats the apps currently running foreground
1045     * service.  The ProcessMap is package/uid tuples; each of these contain
1046     * an array of the currently foreground processes.
1047     */
1048    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1049            = new ProcessMap<ArrayList<ProcessRecord>>();
1050
1051    /**
1052     * This is set if we had to do a delayed dexopt of an app before launching
1053     * it, to increase the ANR timeouts in that case.
1054     */
1055    boolean mDidDexOpt;
1056
1057    /**
1058     * Set if the systemServer made a call to enterSafeMode.
1059     */
1060    boolean mSafeMode;
1061
1062    String mDebugApp = null;
1063    boolean mWaitForDebugger = false;
1064    boolean mDebugTransient = false;
1065    String mOrigDebugApp = null;
1066    boolean mOrigWaitForDebugger = false;
1067    boolean mAlwaysFinishActivities = false;
1068    IActivityController mController = null;
1069    String mProfileApp = null;
1070    ProcessRecord mProfileProc = null;
1071    String mProfileFile;
1072    ParcelFileDescriptor mProfileFd;
1073    int mSamplingInterval = 0;
1074    boolean mAutoStopProfiler = false;
1075    int mProfileType = 0;
1076    String mOpenGlTraceApp = null;
1077
1078    static class ProcessChangeItem {
1079        static final int CHANGE_ACTIVITIES = 1<<0;
1080        static final int CHANGE_PROCESS_STATE = 1<<1;
1081        int changes;
1082        int uid;
1083        int pid;
1084        int processState;
1085        boolean foregroundActivities;
1086    }
1087
1088    final RemoteCallbackList<IProcessObserver> mProcessObservers
1089            = new RemoteCallbackList<IProcessObserver>();
1090    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1091
1092    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1093            = new ArrayList<ProcessChangeItem>();
1094    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1095            = new ArrayList<ProcessChangeItem>();
1096
1097    /**
1098     * Runtime CPU use collection thread.  This object's lock is used to
1099     * perform synchronization with the thread (notifying it to run).
1100     */
1101    final Thread mProcessCpuThread;
1102
1103    /**
1104     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1105     * Must acquire this object's lock when accessing it.
1106     * NOTE: this lock will be held while doing long operations (trawling
1107     * through all processes in /proc), so it should never be acquired by
1108     * any critical paths such as when holding the main activity manager lock.
1109     */
1110    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1111            MONITOR_THREAD_CPU_USAGE);
1112    final AtomicLong mLastCpuTime = new AtomicLong(0);
1113    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1114
1115    long mLastWriteTime = 0;
1116
1117    /**
1118     * Used to retain an update lock when the foreground activity is in
1119     * immersive mode.
1120     */
1121    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1122
1123    /**
1124     * Set to true after the system has finished booting.
1125     */
1126    boolean mBooted = false;
1127
1128    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1129    int mProcessLimitOverride = -1;
1130
1131    WindowManagerService mWindowManager;
1132
1133    final ActivityThread mSystemThread;
1134
1135    // Holds the current foreground user's id
1136    int mCurrentUserId = 0;
1137    // Holds the target user's id during a user switch
1138    int mTargetUserId = UserHandle.USER_NULL;
1139    // If there are multiple profiles for the current user, their ids are here
1140    // Currently only the primary user can have managed profiles
1141    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1142
1143    /**
1144     * Mapping from each known user ID to the profile group ID it is associated with.
1145     */
1146    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1147
1148    private UserManagerService mUserManager;
1149
1150    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1151        final ProcessRecord mApp;
1152        final int mPid;
1153        final IApplicationThread mAppThread;
1154
1155        AppDeathRecipient(ProcessRecord app, int pid,
1156                IApplicationThread thread) {
1157            if (localLOGV) Slog.v(
1158                TAG, "New death recipient " + this
1159                + " for thread " + thread.asBinder());
1160            mApp = app;
1161            mPid = pid;
1162            mAppThread = thread;
1163        }
1164
1165        @Override
1166        public void binderDied() {
1167            if (localLOGV) Slog.v(
1168                TAG, "Death received in " + this
1169                + " for thread " + mAppThread.asBinder());
1170            synchronized(ActivityManagerService.this) {
1171                appDiedLocked(mApp, mPid, mAppThread);
1172            }
1173        }
1174    }
1175
1176    static final int SHOW_ERROR_MSG = 1;
1177    static final int SHOW_NOT_RESPONDING_MSG = 2;
1178    static final int SHOW_FACTORY_ERROR_MSG = 3;
1179    static final int UPDATE_CONFIGURATION_MSG = 4;
1180    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1181    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1182    static final int SERVICE_TIMEOUT_MSG = 12;
1183    static final int UPDATE_TIME_ZONE = 13;
1184    static final int SHOW_UID_ERROR_MSG = 14;
1185    static final int IM_FEELING_LUCKY_MSG = 15;
1186    static final int PROC_START_TIMEOUT_MSG = 20;
1187    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1188    static final int KILL_APPLICATION_MSG = 22;
1189    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1190    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1191    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1192    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1193    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1194    static final int CLEAR_DNS_CACHE_MSG = 28;
1195    static final int UPDATE_HTTP_PROXY_MSG = 29;
1196    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1197    static final int DISPATCH_PROCESSES_CHANGED = 31;
1198    static final int DISPATCH_PROCESS_DIED = 32;
1199    static final int REPORT_MEM_USAGE_MSG = 33;
1200    static final int REPORT_USER_SWITCH_MSG = 34;
1201    static final int CONTINUE_USER_SWITCH_MSG = 35;
1202    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1203    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1204    static final int PERSIST_URI_GRANTS_MSG = 38;
1205    static final int REQUEST_ALL_PSS_MSG = 39;
1206    static final int START_PROFILES_MSG = 40;
1207    static final int UPDATE_TIME = 41;
1208    static final int SYSTEM_USER_START_MSG = 42;
1209    static final int SYSTEM_USER_CURRENT_MSG = 43;
1210    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1211    static final int FINISH_BOOTING_MSG = 45;
1212    static final int START_USER_SWITCH_MSG = 46;
1213    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1214
1215    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1216    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1217    static final int FIRST_COMPAT_MODE_MSG = 300;
1218    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1219
1220    AlertDialog mUidAlert;
1221    CompatModeDialog mCompatModeDialog;
1222    long mLastMemUsageReportTime = 0;
1223
1224    /**
1225     * Flag whether the current user is a "monkey", i.e. whether
1226     * the UI is driven by a UI automation tool.
1227     */
1228    private boolean mUserIsMonkey;
1229
1230    /** Flag whether the device has a Recents UI */
1231    boolean mHasRecents;
1232
1233    /** The dimensions of the thumbnails in the Recents UI. */
1234    int mThumbnailWidth;
1235    int mThumbnailHeight;
1236
1237    final ServiceThread mHandlerThread;
1238    final MainHandler mHandler;
1239
1240    final class MainHandler extends Handler {
1241        public MainHandler(Looper looper) {
1242            super(looper, null, true);
1243        }
1244
1245        @Override
1246        public void handleMessage(Message msg) {
1247            switch (msg.what) {
1248            case SHOW_ERROR_MSG: {
1249                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1250                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1251                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1252                synchronized (ActivityManagerService.this) {
1253                    ProcessRecord proc = (ProcessRecord)data.get("app");
1254                    AppErrorResult res = (AppErrorResult) data.get("result");
1255                    if (proc != null && proc.crashDialog != null) {
1256                        Slog.e(TAG, "App already has crash dialog: " + proc);
1257                        if (res != null) {
1258                            res.set(0);
1259                        }
1260                        return;
1261                    }
1262                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1263                            >= Process.FIRST_APPLICATION_UID
1264                            && proc.pid != MY_PID);
1265                    for (int userId : mCurrentProfileIds) {
1266                        isBackground &= (proc.userId != userId);
1267                    }
1268                    if (isBackground && !showBackground) {
1269                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1270                        if (res != null) {
1271                            res.set(0);
1272                        }
1273                        return;
1274                    }
1275                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1276                        Dialog d = new AppErrorDialog(mContext,
1277                                ActivityManagerService.this, res, proc);
1278                        d.show();
1279                        proc.crashDialog = d;
1280                    } else {
1281                        // The device is asleep, so just pretend that the user
1282                        // saw a crash dialog and hit "force quit".
1283                        if (res != null) {
1284                            res.set(0);
1285                        }
1286                    }
1287                }
1288
1289                ensureBootCompleted();
1290            } break;
1291            case SHOW_NOT_RESPONDING_MSG: {
1292                synchronized (ActivityManagerService.this) {
1293                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1294                    ProcessRecord proc = (ProcessRecord)data.get("app");
1295                    if (proc != null && proc.anrDialog != null) {
1296                        Slog.e(TAG, "App already has anr dialog: " + proc);
1297                        return;
1298                    }
1299
1300                    Intent intent = new Intent("android.intent.action.ANR");
1301                    if (!mProcessesReady) {
1302                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1303                                | Intent.FLAG_RECEIVER_FOREGROUND);
1304                    }
1305                    broadcastIntentLocked(null, null, intent,
1306                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1307                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1308
1309                    if (mShowDialogs) {
1310                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1311                                mContext, proc, (ActivityRecord)data.get("activity"),
1312                                msg.arg1 != 0);
1313                        d.show();
1314                        proc.anrDialog = d;
1315                    } else {
1316                        // Just kill the app if there is no dialog to be shown.
1317                        killAppAtUsersRequest(proc, null);
1318                    }
1319                }
1320
1321                ensureBootCompleted();
1322            } break;
1323            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1324                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1325                synchronized (ActivityManagerService.this) {
1326                    ProcessRecord proc = (ProcessRecord) data.get("app");
1327                    if (proc == null) {
1328                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1329                        break;
1330                    }
1331                    if (proc.crashDialog != null) {
1332                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1333                        return;
1334                    }
1335                    AppErrorResult res = (AppErrorResult) data.get("result");
1336                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1337                        Dialog d = new StrictModeViolationDialog(mContext,
1338                                ActivityManagerService.this, res, proc);
1339                        d.show();
1340                        proc.crashDialog = d;
1341                    } else {
1342                        // The device is asleep, so just pretend that the user
1343                        // saw a crash dialog and hit "force quit".
1344                        res.set(0);
1345                    }
1346                }
1347                ensureBootCompleted();
1348            } break;
1349            case SHOW_FACTORY_ERROR_MSG: {
1350                Dialog d = new FactoryErrorDialog(
1351                    mContext, msg.getData().getCharSequence("msg"));
1352                d.show();
1353                ensureBootCompleted();
1354            } break;
1355            case UPDATE_CONFIGURATION_MSG: {
1356                final ContentResolver resolver = mContext.getContentResolver();
1357                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1358            } break;
1359            case GC_BACKGROUND_PROCESSES_MSG: {
1360                synchronized (ActivityManagerService.this) {
1361                    performAppGcsIfAppropriateLocked();
1362                }
1363            } break;
1364            case WAIT_FOR_DEBUGGER_MSG: {
1365                synchronized (ActivityManagerService.this) {
1366                    ProcessRecord app = (ProcessRecord)msg.obj;
1367                    if (msg.arg1 != 0) {
1368                        if (!app.waitedForDebugger) {
1369                            Dialog d = new AppWaitingForDebuggerDialog(
1370                                    ActivityManagerService.this,
1371                                    mContext, app);
1372                            app.waitDialog = d;
1373                            app.waitedForDebugger = true;
1374                            d.show();
1375                        }
1376                    } else {
1377                        if (app.waitDialog != null) {
1378                            app.waitDialog.dismiss();
1379                            app.waitDialog = null;
1380                        }
1381                    }
1382                }
1383            } break;
1384            case SERVICE_TIMEOUT_MSG: {
1385                if (mDidDexOpt) {
1386                    mDidDexOpt = false;
1387                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1388                    nmsg.obj = msg.obj;
1389                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1390                    return;
1391                }
1392                mServices.serviceTimeout((ProcessRecord)msg.obj);
1393            } break;
1394            case UPDATE_TIME_ZONE: {
1395                synchronized (ActivityManagerService.this) {
1396                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1397                        ProcessRecord r = mLruProcesses.get(i);
1398                        if (r.thread != null) {
1399                            try {
1400                                r.thread.updateTimeZone();
1401                            } catch (RemoteException ex) {
1402                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1403                            }
1404                        }
1405                    }
1406                }
1407            } break;
1408            case CLEAR_DNS_CACHE_MSG: {
1409                synchronized (ActivityManagerService.this) {
1410                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1411                        ProcessRecord r = mLruProcesses.get(i);
1412                        if (r.thread != null) {
1413                            try {
1414                                r.thread.clearDnsCache();
1415                            } catch (RemoteException ex) {
1416                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1417                            }
1418                        }
1419                    }
1420                }
1421            } break;
1422            case UPDATE_HTTP_PROXY_MSG: {
1423                ProxyInfo proxy = (ProxyInfo)msg.obj;
1424                String host = "";
1425                String port = "";
1426                String exclList = "";
1427                Uri pacFileUrl = Uri.EMPTY;
1428                if (proxy != null) {
1429                    host = proxy.getHost();
1430                    port = Integer.toString(proxy.getPort());
1431                    exclList = proxy.getExclusionListAsString();
1432                    pacFileUrl = proxy.getPacFileUrl();
1433                }
1434                synchronized (ActivityManagerService.this) {
1435                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1436                        ProcessRecord r = mLruProcesses.get(i);
1437                        if (r.thread != null) {
1438                            try {
1439                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1440                            } catch (RemoteException ex) {
1441                                Slog.w(TAG, "Failed to update http proxy for: " +
1442                                        r.info.processName);
1443                            }
1444                        }
1445                    }
1446                }
1447            } break;
1448            case SHOW_UID_ERROR_MSG: {
1449                String title = "System UIDs Inconsistent";
1450                String text = "UIDs on the system are inconsistent, you need to wipe your"
1451                        + " data partition or your device will be unstable.";
1452                Log.e(TAG, title + ": " + text);
1453                if (mShowDialogs) {
1454                    // XXX This is a temporary dialog, no need to localize.
1455                    AlertDialog d = new BaseErrorDialog(mContext);
1456                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1457                    d.setCancelable(false);
1458                    d.setTitle(title);
1459                    d.setMessage(text);
1460                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1461                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1462                    mUidAlert = d;
1463                    d.show();
1464                }
1465            } break;
1466            case IM_FEELING_LUCKY_MSG: {
1467                if (mUidAlert != null) {
1468                    mUidAlert.dismiss();
1469                    mUidAlert = null;
1470                }
1471            } break;
1472            case PROC_START_TIMEOUT_MSG: {
1473                if (mDidDexOpt) {
1474                    mDidDexOpt = false;
1475                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1476                    nmsg.obj = msg.obj;
1477                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1478                    return;
1479                }
1480                ProcessRecord app = (ProcessRecord)msg.obj;
1481                synchronized (ActivityManagerService.this) {
1482                    processStartTimedOutLocked(app);
1483                }
1484            } break;
1485            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1486                synchronized (ActivityManagerService.this) {
1487                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1488                }
1489            } break;
1490            case KILL_APPLICATION_MSG: {
1491                synchronized (ActivityManagerService.this) {
1492                    int appid = msg.arg1;
1493                    boolean restart = (msg.arg2 == 1);
1494                    Bundle bundle = (Bundle)msg.obj;
1495                    String pkg = bundle.getString("pkg");
1496                    String reason = bundle.getString("reason");
1497                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1498                            false, UserHandle.USER_ALL, reason);
1499                }
1500            } break;
1501            case FINALIZE_PENDING_INTENT_MSG: {
1502                ((PendingIntentRecord)msg.obj).completeFinalize();
1503            } break;
1504            case POST_HEAVY_NOTIFICATION_MSG: {
1505                INotificationManager inm = NotificationManager.getService();
1506                if (inm == null) {
1507                    return;
1508                }
1509
1510                ActivityRecord root = (ActivityRecord)msg.obj;
1511                ProcessRecord process = root.app;
1512                if (process == null) {
1513                    return;
1514                }
1515
1516                try {
1517                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1518                    String text = mContext.getString(R.string.heavy_weight_notification,
1519                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1520                    Notification notification = new Notification();
1521                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1522                    notification.when = 0;
1523                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1524                    notification.tickerText = text;
1525                    notification.defaults = 0; // please be quiet
1526                    notification.sound = null;
1527                    notification.vibrate = null;
1528                    notification.color = mContext.getResources().getColor(
1529                            com.android.internal.R.color.system_notification_accent_color);
1530                    notification.setLatestEventInfo(context, text,
1531                            mContext.getText(R.string.heavy_weight_notification_detail),
1532                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1533                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1534                                    new UserHandle(root.userId)));
1535
1536                    try {
1537                        int[] outId = new int[1];
1538                        inm.enqueueNotificationWithTag("android", "android", null,
1539                                R.string.heavy_weight_notification,
1540                                notification, outId, root.userId);
1541                    } catch (RuntimeException e) {
1542                        Slog.w(ActivityManagerService.TAG,
1543                                "Error showing notification for heavy-weight app", e);
1544                    } catch (RemoteException e) {
1545                    }
1546                } catch (NameNotFoundException e) {
1547                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1548                }
1549            } break;
1550            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1551                INotificationManager inm = NotificationManager.getService();
1552                if (inm == null) {
1553                    return;
1554                }
1555                try {
1556                    inm.cancelNotificationWithTag("android", null,
1557                            R.string.heavy_weight_notification,  msg.arg1);
1558                } catch (RuntimeException e) {
1559                    Slog.w(ActivityManagerService.TAG,
1560                            "Error canceling notification for service", e);
1561                } catch (RemoteException e) {
1562                }
1563            } break;
1564            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1565                synchronized (ActivityManagerService.this) {
1566                    checkExcessivePowerUsageLocked(true);
1567                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1568                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1569                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1570                }
1571            } break;
1572            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1573                synchronized (ActivityManagerService.this) {
1574                    ActivityRecord ar = (ActivityRecord)msg.obj;
1575                    if (mCompatModeDialog != null) {
1576                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1577                                ar.info.applicationInfo.packageName)) {
1578                            return;
1579                        }
1580                        mCompatModeDialog.dismiss();
1581                        mCompatModeDialog = null;
1582                    }
1583                    if (ar != null && false) {
1584                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1585                                ar.packageName)) {
1586                            int mode = mCompatModePackages.computeCompatModeLocked(
1587                                    ar.info.applicationInfo);
1588                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1589                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1590                                mCompatModeDialog = new CompatModeDialog(
1591                                        ActivityManagerService.this, mContext,
1592                                        ar.info.applicationInfo);
1593                                mCompatModeDialog.show();
1594                            }
1595                        }
1596                    }
1597                }
1598                break;
1599            }
1600            case DISPATCH_PROCESSES_CHANGED: {
1601                dispatchProcessesChanged();
1602                break;
1603            }
1604            case DISPATCH_PROCESS_DIED: {
1605                final int pid = msg.arg1;
1606                final int uid = msg.arg2;
1607                dispatchProcessDied(pid, uid);
1608                break;
1609            }
1610            case REPORT_MEM_USAGE_MSG: {
1611                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1612                Thread thread = new Thread() {
1613                    @Override public void run() {
1614                        reportMemUsage(memInfos);
1615                    }
1616                };
1617                thread.start();
1618                break;
1619            }
1620            case START_USER_SWITCH_MSG: {
1621                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1622                break;
1623            }
1624            case REPORT_USER_SWITCH_MSG: {
1625                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1626                break;
1627            }
1628            case CONTINUE_USER_SWITCH_MSG: {
1629                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1630                break;
1631            }
1632            case USER_SWITCH_TIMEOUT_MSG: {
1633                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1634                break;
1635            }
1636            case IMMERSIVE_MODE_LOCK_MSG: {
1637                final boolean nextState = (msg.arg1 != 0);
1638                if (mUpdateLock.isHeld() != nextState) {
1639                    if (DEBUG_IMMERSIVE) {
1640                        final ActivityRecord r = (ActivityRecord) msg.obj;
1641                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1642                    }
1643                    if (nextState) {
1644                        mUpdateLock.acquire();
1645                    } else {
1646                        mUpdateLock.release();
1647                    }
1648                }
1649                break;
1650            }
1651            case PERSIST_URI_GRANTS_MSG: {
1652                writeGrantedUriPermissions();
1653                break;
1654            }
1655            case REQUEST_ALL_PSS_MSG: {
1656                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1657                break;
1658            }
1659            case START_PROFILES_MSG: {
1660                synchronized (ActivityManagerService.this) {
1661                    startProfilesLocked();
1662                }
1663                break;
1664            }
1665            case UPDATE_TIME: {
1666                synchronized (ActivityManagerService.this) {
1667                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1668                        ProcessRecord r = mLruProcesses.get(i);
1669                        if (r.thread != null) {
1670                            try {
1671                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1672                            } catch (RemoteException ex) {
1673                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1674                            }
1675                        }
1676                    }
1677                }
1678                break;
1679            }
1680            case SYSTEM_USER_START_MSG: {
1681                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1682                        Integer.toString(msg.arg1), msg.arg1);
1683                mSystemServiceManager.startUser(msg.arg1);
1684                break;
1685            }
1686            case SYSTEM_USER_CURRENT_MSG: {
1687                mBatteryStatsService.noteEvent(
1688                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1689                        Integer.toString(msg.arg2), msg.arg2);
1690                mBatteryStatsService.noteEvent(
1691                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1692                        Integer.toString(msg.arg1), msg.arg1);
1693                mSystemServiceManager.switchUser(msg.arg1);
1694                break;
1695            }
1696            case ENTER_ANIMATION_COMPLETE_MSG: {
1697                synchronized (ActivityManagerService.this) {
1698                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1699                    if (r != null && r.app != null && r.app.thread != null) {
1700                        try {
1701                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1702                        } catch (RemoteException e) {
1703                        }
1704                    }
1705                }
1706                break;
1707            }
1708            case FINISH_BOOTING_MSG: {
1709                if (msg.arg1 != 0) {
1710                    finishBooting();
1711                }
1712                if (msg.arg2 != 0) {
1713                    enableScreenAfterBoot();
1714                }
1715                break;
1716            }
1717            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1718                try {
1719                    Locale l = (Locale) msg.obj;
1720                    IBinder service = ServiceManager.getService("mount");
1721                    IMountService mountService = IMountService.Stub.asInterface(service);
1722                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1723                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1724                } catch (RemoteException e) {
1725                    Log.e(TAG, "Error storing locale for decryption UI", e);
1726                }
1727                break;
1728            }
1729            }
1730        }
1731    };
1732
1733    static final int COLLECT_PSS_BG_MSG = 1;
1734
1735    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1736        @Override
1737        public void handleMessage(Message msg) {
1738            switch (msg.what) {
1739            case COLLECT_PSS_BG_MSG: {
1740                long start = SystemClock.uptimeMillis();
1741                MemInfoReader memInfo = null;
1742                synchronized (ActivityManagerService.this) {
1743                    if (mFullPssPending) {
1744                        mFullPssPending = false;
1745                        memInfo = new MemInfoReader();
1746                    }
1747                }
1748                if (memInfo != null) {
1749                    updateCpuStatsNow();
1750                    long nativeTotalPss = 0;
1751                    synchronized (mProcessCpuTracker) {
1752                        final int N = mProcessCpuTracker.countStats();
1753                        for (int j=0; j<N; j++) {
1754                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1755                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1756                                // This is definitely an application process; skip it.
1757                                continue;
1758                            }
1759                            synchronized (mPidsSelfLocked) {
1760                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1761                                    // This is one of our own processes; skip it.
1762                                    continue;
1763                                }
1764                            }
1765                            nativeTotalPss += Debug.getPss(st.pid, null);
1766                        }
1767                    }
1768                    memInfo.readMemInfo();
1769                    synchronized (ActivityManagerService.this) {
1770                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1771                                + (SystemClock.uptimeMillis()-start) + "ms");
1772                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1773                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1774                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1775                    }
1776                }
1777
1778                int i=0, num=0;
1779                long[] tmp = new long[1];
1780                do {
1781                    ProcessRecord proc;
1782                    int procState;
1783                    int pid;
1784                    synchronized (ActivityManagerService.this) {
1785                        if (i >= mPendingPssProcesses.size()) {
1786                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1787                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1788                            mPendingPssProcesses.clear();
1789                            return;
1790                        }
1791                        proc = mPendingPssProcesses.get(i);
1792                        procState = proc.pssProcState;
1793                        if (proc.thread != null && procState == proc.setProcState) {
1794                            pid = proc.pid;
1795                        } else {
1796                            proc = null;
1797                            pid = 0;
1798                        }
1799                        i++;
1800                    }
1801                    if (proc != null) {
1802                        long pss = Debug.getPss(pid, tmp);
1803                        synchronized (ActivityManagerService.this) {
1804                            if (proc.thread != null && proc.setProcState == procState
1805                                    && proc.pid == pid) {
1806                                num++;
1807                                proc.lastPssTime = SystemClock.uptimeMillis();
1808                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1809                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1810                                        + ": " + pss + " lastPss=" + proc.lastPss
1811                                        + " state=" + ProcessList.makeProcStateString(procState));
1812                                if (proc.initialIdlePss == 0) {
1813                                    proc.initialIdlePss = pss;
1814                                }
1815                                proc.lastPss = pss;
1816                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1817                                    proc.lastCachedPss = pss;
1818                                }
1819                            }
1820                        }
1821                    }
1822                } while (true);
1823            }
1824            }
1825        }
1826    };
1827
1828    public void setSystemProcess() {
1829        try {
1830            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1831            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1832            ServiceManager.addService("meminfo", new MemBinder(this));
1833            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1834            ServiceManager.addService("dbinfo", new DbBinder(this));
1835            if (MONITOR_CPU_USAGE) {
1836                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1837            }
1838            ServiceManager.addService("permission", new PermissionController(this));
1839
1840            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1841                    "android", STOCK_PM_FLAGS);
1842            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1843
1844            synchronized (this) {
1845                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1846                app.persistent = true;
1847                app.pid = MY_PID;
1848                app.maxAdj = ProcessList.SYSTEM_ADJ;
1849                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1850                mProcessNames.put(app.processName, app.uid, app);
1851                synchronized (mPidsSelfLocked) {
1852                    mPidsSelfLocked.put(app.pid, app);
1853                }
1854                updateLruProcessLocked(app, false, null);
1855                updateOomAdjLocked();
1856            }
1857        } catch (PackageManager.NameNotFoundException e) {
1858            throw new RuntimeException(
1859                    "Unable to find android system package", e);
1860        }
1861    }
1862
1863    public void setWindowManager(WindowManagerService wm) {
1864        mWindowManager = wm;
1865        mStackSupervisor.setWindowManager(wm);
1866    }
1867
1868    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1869        mUsageStatsService = usageStatsManager;
1870    }
1871
1872    public void startObservingNativeCrashes() {
1873        final NativeCrashListener ncl = new NativeCrashListener(this);
1874        ncl.start();
1875    }
1876
1877    public IAppOpsService getAppOpsService() {
1878        return mAppOpsService;
1879    }
1880
1881    static class MemBinder extends Binder {
1882        ActivityManagerService mActivityManagerService;
1883        MemBinder(ActivityManagerService activityManagerService) {
1884            mActivityManagerService = activityManagerService;
1885        }
1886
1887        @Override
1888        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1889            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1890                    != PackageManager.PERMISSION_GRANTED) {
1891                pw.println("Permission Denial: can't dump meminfo from from pid="
1892                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1893                        + " without permission " + android.Manifest.permission.DUMP);
1894                return;
1895            }
1896
1897            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1898        }
1899    }
1900
1901    static class GraphicsBinder extends Binder {
1902        ActivityManagerService mActivityManagerService;
1903        GraphicsBinder(ActivityManagerService activityManagerService) {
1904            mActivityManagerService = activityManagerService;
1905        }
1906
1907        @Override
1908        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1909            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1910                    != PackageManager.PERMISSION_GRANTED) {
1911                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1912                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1913                        + " without permission " + android.Manifest.permission.DUMP);
1914                return;
1915            }
1916
1917            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1918        }
1919    }
1920
1921    static class DbBinder extends Binder {
1922        ActivityManagerService mActivityManagerService;
1923        DbBinder(ActivityManagerService activityManagerService) {
1924            mActivityManagerService = activityManagerService;
1925        }
1926
1927        @Override
1928        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1929            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1930                    != PackageManager.PERMISSION_GRANTED) {
1931                pw.println("Permission Denial: can't dump dbinfo from from pid="
1932                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1933                        + " without permission " + android.Manifest.permission.DUMP);
1934                return;
1935            }
1936
1937            mActivityManagerService.dumpDbInfo(fd, pw, args);
1938        }
1939    }
1940
1941    static class CpuBinder extends Binder {
1942        ActivityManagerService mActivityManagerService;
1943        CpuBinder(ActivityManagerService activityManagerService) {
1944            mActivityManagerService = activityManagerService;
1945        }
1946
1947        @Override
1948        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1949            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1950                    != PackageManager.PERMISSION_GRANTED) {
1951                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1952                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1953                        + " without permission " + android.Manifest.permission.DUMP);
1954                return;
1955            }
1956
1957            synchronized (mActivityManagerService.mProcessCpuTracker) {
1958                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1959                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1960                        SystemClock.uptimeMillis()));
1961            }
1962        }
1963    }
1964
1965    public static final class Lifecycle extends SystemService {
1966        private final ActivityManagerService mService;
1967
1968        public Lifecycle(Context context) {
1969            super(context);
1970            mService = new ActivityManagerService(context);
1971        }
1972
1973        @Override
1974        public void onStart() {
1975            mService.start();
1976        }
1977
1978        public ActivityManagerService getService() {
1979            return mService;
1980        }
1981    }
1982
1983    // Note: This method is invoked on the main thread but may need to attach various
1984    // handlers to other threads.  So take care to be explicit about the looper.
1985    public ActivityManagerService(Context systemContext) {
1986        mContext = systemContext;
1987        mFactoryTest = FactoryTest.getMode();
1988        mSystemThread = ActivityThread.currentActivityThread();
1989
1990        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1991
1992        mHandlerThread = new ServiceThread(TAG,
1993                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1994        mHandlerThread.start();
1995        mHandler = new MainHandler(mHandlerThread.getLooper());
1996
1997        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1998                "foreground", BROADCAST_FG_TIMEOUT, false);
1999        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2000                "background", BROADCAST_BG_TIMEOUT, true);
2001        mBroadcastQueues[0] = mFgBroadcastQueue;
2002        mBroadcastQueues[1] = mBgBroadcastQueue;
2003
2004        mServices = new ActiveServices(this);
2005        mProviderMap = new ProviderMap(this);
2006
2007        // TODO: Move creation of battery stats service outside of activity manager service.
2008        File dataDir = Environment.getDataDirectory();
2009        File systemDir = new File(dataDir, "system");
2010        systemDir.mkdirs();
2011        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2012        mBatteryStatsService.getActiveStatistics().readLocked();
2013        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2014        mOnBattery = DEBUG_POWER ? true
2015                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2016        mBatteryStatsService.getActiveStatistics().setCallback(this);
2017
2018        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2019
2020        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2021
2022        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2023
2024        // User 0 is the first and only user that runs at boot.
2025        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2026        mUserLru.add(Integer.valueOf(0));
2027        updateStartedUserArrayLocked();
2028
2029        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2030            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2031
2032        mConfiguration.setToDefaults();
2033        mConfiguration.setLocale(Locale.getDefault());
2034
2035        mConfigurationSeq = mConfiguration.seq = 1;
2036        mProcessCpuTracker.init();
2037
2038        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2039        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2040        mStackSupervisor = new ActivityStackSupervisor(this);
2041        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2042
2043        mProcessCpuThread = new Thread("CpuTracker") {
2044            @Override
2045            public void run() {
2046                while (true) {
2047                    try {
2048                        try {
2049                            synchronized(this) {
2050                                final long now = SystemClock.uptimeMillis();
2051                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2052                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2053                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2054                                //        + ", write delay=" + nextWriteDelay);
2055                                if (nextWriteDelay < nextCpuDelay) {
2056                                    nextCpuDelay = nextWriteDelay;
2057                                }
2058                                if (nextCpuDelay > 0) {
2059                                    mProcessCpuMutexFree.set(true);
2060                                    this.wait(nextCpuDelay);
2061                                }
2062                            }
2063                        } catch (InterruptedException e) {
2064                        }
2065                        updateCpuStatsNow();
2066                    } catch (Exception e) {
2067                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2068                    }
2069                }
2070            }
2071        };
2072
2073        Watchdog.getInstance().addMonitor(this);
2074        Watchdog.getInstance().addThread(mHandler);
2075    }
2076
2077    public void setSystemServiceManager(SystemServiceManager mgr) {
2078        mSystemServiceManager = mgr;
2079    }
2080
2081    public void setInstaller(Installer installer) {
2082        mInstaller = installer;
2083    }
2084
2085    private void start() {
2086        Process.removeAllProcessGroups();
2087        mProcessCpuThread.start();
2088
2089        mBatteryStatsService.publish(mContext);
2090        mAppOpsService.publish(mContext);
2091        Slog.d("AppOps", "AppOpsService published");
2092        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2093    }
2094
2095    public void initPowerManagement() {
2096        mStackSupervisor.initPowerManagement();
2097        mBatteryStatsService.initPowerManagement();
2098    }
2099
2100    @Override
2101    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2102            throws RemoteException {
2103        if (code == SYSPROPS_TRANSACTION) {
2104            // We need to tell all apps about the system property change.
2105            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2106            synchronized(this) {
2107                final int NP = mProcessNames.getMap().size();
2108                for (int ip=0; ip<NP; ip++) {
2109                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2110                    final int NA = apps.size();
2111                    for (int ia=0; ia<NA; ia++) {
2112                        ProcessRecord app = apps.valueAt(ia);
2113                        if (app.thread != null) {
2114                            procs.add(app.thread.asBinder());
2115                        }
2116                    }
2117                }
2118            }
2119
2120            int N = procs.size();
2121            for (int i=0; i<N; i++) {
2122                Parcel data2 = Parcel.obtain();
2123                try {
2124                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2125                } catch (RemoteException e) {
2126                }
2127                data2.recycle();
2128            }
2129        }
2130        try {
2131            return super.onTransact(code, data, reply, flags);
2132        } catch (RuntimeException e) {
2133            // The activity manager only throws security exceptions, so let's
2134            // log all others.
2135            if (!(e instanceof SecurityException)) {
2136                Slog.wtf(TAG, "Activity Manager Crash", e);
2137            }
2138            throw e;
2139        }
2140    }
2141
2142    void updateCpuStats() {
2143        final long now = SystemClock.uptimeMillis();
2144        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2145            return;
2146        }
2147        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2148            synchronized (mProcessCpuThread) {
2149                mProcessCpuThread.notify();
2150            }
2151        }
2152    }
2153
2154    void updateCpuStatsNow() {
2155        synchronized (mProcessCpuTracker) {
2156            mProcessCpuMutexFree.set(false);
2157            final long now = SystemClock.uptimeMillis();
2158            boolean haveNewCpuStats = false;
2159
2160            if (MONITOR_CPU_USAGE &&
2161                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2162                mLastCpuTime.set(now);
2163                haveNewCpuStats = true;
2164                mProcessCpuTracker.update();
2165                //Slog.i(TAG, mProcessCpu.printCurrentState());
2166                //Slog.i(TAG, "Total CPU usage: "
2167                //        + mProcessCpu.getTotalCpuPercent() + "%");
2168
2169                // Slog the cpu usage if the property is set.
2170                if ("true".equals(SystemProperties.get("events.cpu"))) {
2171                    int user = mProcessCpuTracker.getLastUserTime();
2172                    int system = mProcessCpuTracker.getLastSystemTime();
2173                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2174                    int irq = mProcessCpuTracker.getLastIrqTime();
2175                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2176                    int idle = mProcessCpuTracker.getLastIdleTime();
2177
2178                    int total = user + system + iowait + irq + softIrq + idle;
2179                    if (total == 0) total = 1;
2180
2181                    EventLog.writeEvent(EventLogTags.CPU,
2182                            ((user+system+iowait+irq+softIrq) * 100) / total,
2183                            (user * 100) / total,
2184                            (system * 100) / total,
2185                            (iowait * 100) / total,
2186                            (irq * 100) / total,
2187                            (softIrq * 100) / total);
2188                }
2189            }
2190
2191            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2192            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2193            synchronized(bstats) {
2194                synchronized(mPidsSelfLocked) {
2195                    if (haveNewCpuStats) {
2196                        if (mOnBattery) {
2197                            int perc = bstats.startAddingCpuLocked();
2198                            int totalUTime = 0;
2199                            int totalSTime = 0;
2200                            final int N = mProcessCpuTracker.countStats();
2201                            for (int i=0; i<N; i++) {
2202                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2203                                if (!st.working) {
2204                                    continue;
2205                                }
2206                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2207                                int otherUTime = (st.rel_utime*perc)/100;
2208                                int otherSTime = (st.rel_stime*perc)/100;
2209                                totalUTime += otherUTime;
2210                                totalSTime += otherSTime;
2211                                if (pr != null) {
2212                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2213                                    if (ps == null || !ps.isActive()) {
2214                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2215                                                pr.info.uid, pr.processName);
2216                                    }
2217                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2218                                            st.rel_stime-otherSTime);
2219                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2220                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2221                                } else {
2222                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2223                                    if (ps == null || !ps.isActive()) {
2224                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2225                                                bstats.mapUid(st.uid), st.name);
2226                                    }
2227                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2228                                            st.rel_stime-otherSTime);
2229                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2230                                }
2231                            }
2232                            bstats.finishAddingCpuLocked(perc, totalUTime,
2233                                    totalSTime, cpuSpeedTimes);
2234                        }
2235                    }
2236                }
2237
2238                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2239                    mLastWriteTime = now;
2240                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2241                }
2242            }
2243        }
2244    }
2245
2246    @Override
2247    public void batteryNeedsCpuUpdate() {
2248        updateCpuStatsNow();
2249    }
2250
2251    @Override
2252    public void batteryPowerChanged(boolean onBattery) {
2253        // When plugging in, update the CPU stats first before changing
2254        // the plug state.
2255        updateCpuStatsNow();
2256        synchronized (this) {
2257            synchronized(mPidsSelfLocked) {
2258                mOnBattery = DEBUG_POWER ? true : onBattery;
2259            }
2260        }
2261    }
2262
2263    /**
2264     * Initialize the application bind args. These are passed to each
2265     * process when the bindApplication() IPC is sent to the process. They're
2266     * lazily setup to make sure the services are running when they're asked for.
2267     */
2268    private HashMap<String, IBinder> getCommonServicesLocked() {
2269        if (mAppBindArgs == null) {
2270            mAppBindArgs = new HashMap<String, IBinder>();
2271
2272            // Setup the application init args
2273            mAppBindArgs.put("package", ServiceManager.getService("package"));
2274            mAppBindArgs.put("window", ServiceManager.getService("window"));
2275            mAppBindArgs.put(Context.ALARM_SERVICE,
2276                    ServiceManager.getService(Context.ALARM_SERVICE));
2277        }
2278        return mAppBindArgs;
2279    }
2280
2281    final void setFocusedActivityLocked(ActivityRecord r) {
2282        if (mFocusedActivity != r) {
2283            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2284            mFocusedActivity = r;
2285            if (r.task != null && r.task.voiceInteractor != null) {
2286                startRunningVoiceLocked();
2287            } else {
2288                finishRunningVoiceLocked();
2289            }
2290            mStackSupervisor.setFocusedStack(r);
2291            if (r != null) {
2292                mWindowManager.setFocusedApp(r.appToken, true);
2293            }
2294            applyUpdateLockStateLocked(r);
2295        }
2296    }
2297
2298    final void clearFocusedActivity(ActivityRecord r) {
2299        if (mFocusedActivity == r) {
2300            mFocusedActivity = null;
2301        }
2302    }
2303
2304    @Override
2305    public void setFocusedStack(int stackId) {
2306        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2307        synchronized (ActivityManagerService.this) {
2308            ActivityStack stack = mStackSupervisor.getStack(stackId);
2309            if (stack != null) {
2310                ActivityRecord r = stack.topRunningActivityLocked(null);
2311                if (r != null) {
2312                    setFocusedActivityLocked(r);
2313                }
2314            }
2315        }
2316    }
2317
2318    @Override
2319    public void notifyActivityDrawn(IBinder token) {
2320        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2321        synchronized (this) {
2322            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2323            if (r != null) {
2324                r.task.stack.notifyActivityDrawnLocked(r);
2325            }
2326        }
2327    }
2328
2329    final void applyUpdateLockStateLocked(ActivityRecord r) {
2330        // Modifications to the UpdateLock state are done on our handler, outside
2331        // the activity manager's locks.  The new state is determined based on the
2332        // state *now* of the relevant activity record.  The object is passed to
2333        // the handler solely for logging detail, not to be consulted/modified.
2334        final boolean nextState = r != null && r.immersive;
2335        mHandler.sendMessage(
2336                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2337    }
2338
2339    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2340        Message msg = Message.obtain();
2341        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2342        msg.obj = r.task.askedCompatMode ? null : r;
2343        mHandler.sendMessage(msg);
2344    }
2345
2346    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2347            String what, Object obj, ProcessRecord srcApp) {
2348        app.lastActivityTime = now;
2349
2350        if (app.activities.size() > 0) {
2351            // Don't want to touch dependent processes that are hosting activities.
2352            return index;
2353        }
2354
2355        int lrui = mLruProcesses.lastIndexOf(app);
2356        if (lrui < 0) {
2357            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2358                    + what + " " + obj + " from " + srcApp);
2359            return index;
2360        }
2361
2362        if (lrui >= index) {
2363            // Don't want to cause this to move dependent processes *back* in the
2364            // list as if they were less frequently used.
2365            return index;
2366        }
2367
2368        if (lrui >= mLruProcessActivityStart) {
2369            // Don't want to touch dependent processes that are hosting activities.
2370            return index;
2371        }
2372
2373        mLruProcesses.remove(lrui);
2374        if (index > 0) {
2375            index--;
2376        }
2377        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2378                + " in LRU list: " + app);
2379        mLruProcesses.add(index, app);
2380        return index;
2381    }
2382
2383    final void removeLruProcessLocked(ProcessRecord app) {
2384        int lrui = mLruProcesses.lastIndexOf(app);
2385        if (lrui >= 0) {
2386            if (!app.killed) {
2387                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2388                Process.killProcessQuiet(app.pid);
2389                Process.killProcessGroup(app.info.uid, app.pid);
2390            }
2391            if (lrui <= mLruProcessActivityStart) {
2392                mLruProcessActivityStart--;
2393            }
2394            if (lrui <= mLruProcessServiceStart) {
2395                mLruProcessServiceStart--;
2396            }
2397            mLruProcesses.remove(lrui);
2398        }
2399    }
2400
2401    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2402            ProcessRecord client) {
2403        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2404                || app.treatLikeActivity;
2405        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2406        if (!activityChange && hasActivity) {
2407            // The process has activities, so we are only allowing activity-based adjustments
2408            // to move it.  It should be kept in the front of the list with other
2409            // processes that have activities, and we don't want those to change their
2410            // order except due to activity operations.
2411            return;
2412        }
2413
2414        mLruSeq++;
2415        final long now = SystemClock.uptimeMillis();
2416        app.lastActivityTime = now;
2417
2418        // First a quick reject: if the app is already at the position we will
2419        // put it, then there is nothing to do.
2420        if (hasActivity) {
2421            final int N = mLruProcesses.size();
2422            if (N > 0 && mLruProcesses.get(N-1) == app) {
2423                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2424                return;
2425            }
2426        } else {
2427            if (mLruProcessServiceStart > 0
2428                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2429                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2430                return;
2431            }
2432        }
2433
2434        int lrui = mLruProcesses.lastIndexOf(app);
2435
2436        if (app.persistent && lrui >= 0) {
2437            // We don't care about the position of persistent processes, as long as
2438            // they are in the list.
2439            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2440            return;
2441        }
2442
2443        /* In progress: compute new position first, so we can avoid doing work
2444           if the process is not actually going to move.  Not yet working.
2445        int addIndex;
2446        int nextIndex;
2447        boolean inActivity = false, inService = false;
2448        if (hasActivity) {
2449            // Process has activities, put it at the very tipsy-top.
2450            addIndex = mLruProcesses.size();
2451            nextIndex = mLruProcessServiceStart;
2452            inActivity = true;
2453        } else if (hasService) {
2454            // Process has services, put it at the top of the service list.
2455            addIndex = mLruProcessActivityStart;
2456            nextIndex = mLruProcessServiceStart;
2457            inActivity = true;
2458            inService = true;
2459        } else  {
2460            // Process not otherwise of interest, it goes to the top of the non-service area.
2461            addIndex = mLruProcessServiceStart;
2462            if (client != null) {
2463                int clientIndex = mLruProcesses.lastIndexOf(client);
2464                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2465                        + app);
2466                if (clientIndex >= 0 && addIndex > clientIndex) {
2467                    addIndex = clientIndex;
2468                }
2469            }
2470            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2471        }
2472
2473        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2474                + mLruProcessActivityStart + "): " + app);
2475        */
2476
2477        if (lrui >= 0) {
2478            if (lrui < mLruProcessActivityStart) {
2479                mLruProcessActivityStart--;
2480            }
2481            if (lrui < mLruProcessServiceStart) {
2482                mLruProcessServiceStart--;
2483            }
2484            /*
2485            if (addIndex > lrui) {
2486                addIndex--;
2487            }
2488            if (nextIndex > lrui) {
2489                nextIndex--;
2490            }
2491            */
2492            mLruProcesses.remove(lrui);
2493        }
2494
2495        /*
2496        mLruProcesses.add(addIndex, app);
2497        if (inActivity) {
2498            mLruProcessActivityStart++;
2499        }
2500        if (inService) {
2501            mLruProcessActivityStart++;
2502        }
2503        */
2504
2505        int nextIndex;
2506        if (hasActivity) {
2507            final int N = mLruProcesses.size();
2508            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2509                // Process doesn't have activities, but has clients with
2510                // activities...  move it up, but one below the top (the top
2511                // should always have a real activity).
2512                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2513                mLruProcesses.add(N-1, app);
2514                // To keep it from spamming the LRU list (by making a bunch of clients),
2515                // we will push down any other entries owned by the app.
2516                final int uid = app.info.uid;
2517                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2518                    ProcessRecord subProc = mLruProcesses.get(i);
2519                    if (subProc.info.uid == uid) {
2520                        // We want to push this one down the list.  If the process after
2521                        // it is for the same uid, however, don't do so, because we don't
2522                        // want them internally to be re-ordered.
2523                        if (mLruProcesses.get(i-1).info.uid != uid) {
2524                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2525                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2526                            ProcessRecord tmp = mLruProcesses.get(i);
2527                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2528                            mLruProcesses.set(i-1, tmp);
2529                            i--;
2530                        }
2531                    } else {
2532                        // A gap, we can stop here.
2533                        break;
2534                    }
2535                }
2536            } else {
2537                // Process has activities, put it at the very tipsy-top.
2538                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2539                mLruProcesses.add(app);
2540            }
2541            nextIndex = mLruProcessServiceStart;
2542        } else if (hasService) {
2543            // Process has services, put it at the top of the service list.
2544            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2545            mLruProcesses.add(mLruProcessActivityStart, app);
2546            nextIndex = mLruProcessServiceStart;
2547            mLruProcessActivityStart++;
2548        } else  {
2549            // Process not otherwise of interest, it goes to the top of the non-service area.
2550            int index = mLruProcessServiceStart;
2551            if (client != null) {
2552                // If there is a client, don't allow the process to be moved up higher
2553                // in the list than that client.
2554                int clientIndex = mLruProcesses.lastIndexOf(client);
2555                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2556                        + " when updating " + app);
2557                if (clientIndex <= lrui) {
2558                    // Don't allow the client index restriction to push it down farther in the
2559                    // list than it already is.
2560                    clientIndex = lrui;
2561                }
2562                if (clientIndex >= 0 && index > clientIndex) {
2563                    index = clientIndex;
2564                }
2565            }
2566            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2567            mLruProcesses.add(index, app);
2568            nextIndex = index-1;
2569            mLruProcessActivityStart++;
2570            mLruProcessServiceStart++;
2571        }
2572
2573        // If the app is currently using a content provider or service,
2574        // bump those processes as well.
2575        for (int j=app.connections.size()-1; j>=0; j--) {
2576            ConnectionRecord cr = app.connections.valueAt(j);
2577            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2578                    && cr.binding.service.app != null
2579                    && cr.binding.service.app.lruSeq != mLruSeq
2580                    && !cr.binding.service.app.persistent) {
2581                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2582                        "service connection", cr, app);
2583            }
2584        }
2585        for (int j=app.conProviders.size()-1; j>=0; j--) {
2586            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2587            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2588                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2589                        "provider reference", cpr, app);
2590            }
2591        }
2592    }
2593
2594    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2595        if (uid == Process.SYSTEM_UID) {
2596            // The system gets to run in any process.  If there are multiple
2597            // processes with the same uid, just pick the first (this
2598            // should never happen).
2599            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2600            if (procs == null) return null;
2601            final int N = procs.size();
2602            for (int i = 0; i < N; i++) {
2603                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2604            }
2605        }
2606        ProcessRecord proc = mProcessNames.get(processName, uid);
2607        if (false && proc != null && !keepIfLarge
2608                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2609                && proc.lastCachedPss >= 4000) {
2610            // Turn this condition on to cause killing to happen regularly, for testing.
2611            if (proc.baseProcessTracker != null) {
2612                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2613            }
2614            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2615        } else if (proc != null && !keepIfLarge
2616                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2617                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2618            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2619            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2620                if (proc.baseProcessTracker != null) {
2621                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2622                }
2623                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2624            }
2625        }
2626        return proc;
2627    }
2628
2629    void ensurePackageDexOpt(String packageName) {
2630        IPackageManager pm = AppGlobals.getPackageManager();
2631        try {
2632            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2633                mDidDexOpt = true;
2634            }
2635        } catch (RemoteException e) {
2636        }
2637    }
2638
2639    boolean isNextTransitionForward() {
2640        int transit = mWindowManager.getPendingAppTransition();
2641        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2642                || transit == AppTransition.TRANSIT_TASK_OPEN
2643                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2644    }
2645
2646    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2647            String processName, String abiOverride, int uid, Runnable crashHandler) {
2648        synchronized(this) {
2649            ApplicationInfo info = new ApplicationInfo();
2650            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2651            // For isolated processes, the former contains the parent's uid and the latter the
2652            // actual uid of the isolated process.
2653            // In the special case introduced by this method (which is, starting an isolated
2654            // process directly from the SystemServer without an actual parent app process) the
2655            // closest thing to a parent's uid is SYSTEM_UID.
2656            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2657            // the |isolated| logic in the ProcessRecord constructor.
2658            info.uid = Process.SYSTEM_UID;
2659            info.processName = processName;
2660            info.className = entryPoint;
2661            info.packageName = "android";
2662            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2663                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2664                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2665                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2666                    crashHandler);
2667            return proc != null ? proc.pid : 0;
2668        }
2669    }
2670
2671    final ProcessRecord startProcessLocked(String processName,
2672            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2673            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2674            boolean isolated, boolean keepIfLarge) {
2675        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2676                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2677                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2678                null /* crashHandler */);
2679    }
2680
2681    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2682            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2683            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2684            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2685        long startTime = SystemClock.elapsedRealtime();
2686        ProcessRecord app;
2687        if (!isolated) {
2688            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2689            checkTime(startTime, "startProcess: after getProcessRecord");
2690        } else {
2691            // If this is an isolated process, it can't re-use an existing process.
2692            app = null;
2693        }
2694        // We don't have to do anything more if:
2695        // (1) There is an existing application record; and
2696        // (2) The caller doesn't think it is dead, OR there is no thread
2697        //     object attached to it so we know it couldn't have crashed; and
2698        // (3) There is a pid assigned to it, so it is either starting or
2699        //     already running.
2700        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2701                + " app=" + app + " knownToBeDead=" + knownToBeDead
2702                + " thread=" + (app != null ? app.thread : null)
2703                + " pid=" + (app != null ? app.pid : -1));
2704        if (app != null && app.pid > 0) {
2705            if (!knownToBeDead || app.thread == null) {
2706                // We already have the app running, or are waiting for it to
2707                // come up (we have a pid but not yet its thread), so keep it.
2708                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2709                // If this is a new package in the process, add the package to the list
2710                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2711                checkTime(startTime, "startProcess: done, added package to proc");
2712                return app;
2713            }
2714
2715            // An application record is attached to a previous process,
2716            // clean it up now.
2717            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2718            checkTime(startTime, "startProcess: bad proc running, killing");
2719            Process.killProcessGroup(app.info.uid, app.pid);
2720            handleAppDiedLocked(app, true, true);
2721            checkTime(startTime, "startProcess: done killing old proc");
2722        }
2723
2724        String hostingNameStr = hostingName != null
2725                ? hostingName.flattenToShortString() : null;
2726
2727        if (!isolated) {
2728            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2729                // If we are in the background, then check to see if this process
2730                // is bad.  If so, we will just silently fail.
2731                if (mBadProcesses.get(info.processName, info.uid) != null) {
2732                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2733                            + "/" + info.processName);
2734                    return null;
2735                }
2736            } else {
2737                // When the user is explicitly starting a process, then clear its
2738                // crash count so that we won't make it bad until they see at
2739                // least one crash dialog again, and make the process good again
2740                // if it had been bad.
2741                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2742                        + "/" + info.processName);
2743                mProcessCrashTimes.remove(info.processName, info.uid);
2744                if (mBadProcesses.get(info.processName, info.uid) != null) {
2745                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2746                            UserHandle.getUserId(info.uid), info.uid,
2747                            info.processName);
2748                    mBadProcesses.remove(info.processName, info.uid);
2749                    if (app != null) {
2750                        app.bad = false;
2751                    }
2752                }
2753            }
2754        }
2755
2756        if (app == null) {
2757            checkTime(startTime, "startProcess: creating new process record");
2758            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2759            app.crashHandler = crashHandler;
2760            if (app == null) {
2761                Slog.w(TAG, "Failed making new process record for "
2762                        + processName + "/" + info.uid + " isolated=" + isolated);
2763                return null;
2764            }
2765            mProcessNames.put(processName, app.uid, app);
2766            if (isolated) {
2767                mIsolatedProcesses.put(app.uid, app);
2768            }
2769            checkTime(startTime, "startProcess: done creating new process record");
2770        } else {
2771            // If this is a new package in the process, add the package to the list
2772            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2773            checkTime(startTime, "startProcess: added package to existing proc");
2774        }
2775
2776        // If the system is not ready yet, then hold off on starting this
2777        // process until it is.
2778        if (!mProcessesReady
2779                && !isAllowedWhileBooting(info)
2780                && !allowWhileBooting) {
2781            if (!mProcessesOnHold.contains(app)) {
2782                mProcessesOnHold.add(app);
2783            }
2784            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2785            checkTime(startTime, "startProcess: returning with proc on hold");
2786            return app;
2787        }
2788
2789        checkTime(startTime, "startProcess: stepping in to startProcess");
2790        startProcessLocked(
2791                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2792        checkTime(startTime, "startProcess: done starting proc!");
2793        return (app.pid != 0) ? app : null;
2794    }
2795
2796    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2797        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2798    }
2799
2800    private final void startProcessLocked(ProcessRecord app,
2801            String hostingType, String hostingNameStr) {
2802        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2803                null /* entryPoint */, null /* entryPointArgs */);
2804    }
2805
2806    private final void startProcessLocked(ProcessRecord app, String hostingType,
2807            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2808        long startTime = SystemClock.elapsedRealtime();
2809        if (app.pid > 0 && app.pid != MY_PID) {
2810            checkTime(startTime, "startProcess: removing from pids map");
2811            synchronized (mPidsSelfLocked) {
2812                mPidsSelfLocked.remove(app.pid);
2813                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2814            }
2815            checkTime(startTime, "startProcess: done removing from pids map");
2816            app.setPid(0);
2817        }
2818
2819        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2820                "startProcessLocked removing on hold: " + app);
2821        mProcessesOnHold.remove(app);
2822
2823        checkTime(startTime, "startProcess: starting to update cpu stats");
2824        updateCpuStats();
2825        checkTime(startTime, "startProcess: done updating cpu stats");
2826
2827        try {
2828            int uid = app.uid;
2829
2830            int[] gids = null;
2831            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2832            if (!app.isolated) {
2833                int[] permGids = null;
2834                try {
2835                    checkTime(startTime, "startProcess: getting gids from package manager");
2836                    final PackageManager pm = mContext.getPackageManager();
2837                    permGids = pm.getPackageGids(app.info.packageName);
2838
2839                    if (Environment.isExternalStorageEmulated()) {
2840                        checkTime(startTime, "startProcess: checking external storage perm");
2841                        if (pm.checkPermission(
2842                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2843                                app.info.packageName) == PERMISSION_GRANTED) {
2844                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2845                        } else {
2846                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2847                        }
2848                    }
2849                } catch (PackageManager.NameNotFoundException e) {
2850                    Slog.w(TAG, "Unable to retrieve gids", e);
2851                }
2852
2853                /*
2854                 * Add shared application and profile GIDs so applications can share some
2855                 * resources like shared libraries and access user-wide resources
2856                 */
2857                if (permGids == null) {
2858                    gids = new int[2];
2859                } else {
2860                    gids = new int[permGids.length + 2];
2861                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2862                }
2863                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2864                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2865            }
2866            checkTime(startTime, "startProcess: building args");
2867            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2868                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2869                        && mTopComponent != null
2870                        && app.processName.equals(mTopComponent.getPackageName())) {
2871                    uid = 0;
2872                }
2873                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2874                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2875                    uid = 0;
2876                }
2877            }
2878            int debugFlags = 0;
2879            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2880                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2881                // Also turn on CheckJNI for debuggable apps. It's quite
2882                // awkward to turn on otherwise.
2883                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2884            }
2885            // Run the app in safe mode if its manifest requests so or the
2886            // system is booted in safe mode.
2887            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2888                mSafeMode == true) {
2889                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2890            }
2891            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2892                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2893            }
2894            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2895                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2896            }
2897            if ("1".equals(SystemProperties.get("debug.assert"))) {
2898                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2899            }
2900
2901            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2902            if (requiredAbi == null) {
2903                requiredAbi = Build.SUPPORTED_ABIS[0];
2904            }
2905
2906            String instructionSet = null;
2907            if (app.info.primaryCpuAbi != null) {
2908                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2909            }
2910
2911            // Start the process.  It will either succeed and return a result containing
2912            // the PID of the new process, or else throw a RuntimeException.
2913            boolean isActivityProcess = (entryPoint == null);
2914            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2915            checkTime(startTime, "startProcess: asking zygote to start proc");
2916            Process.ProcessStartResult startResult = Process.start(entryPoint,
2917                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2918                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2919                    app.info.dataDir, entryPointArgs);
2920            checkTime(startTime, "startProcess: returned from zygote!");
2921
2922            if (app.isolated) {
2923                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2924            }
2925            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2926            checkTime(startTime, "startProcess: done updating battery stats");
2927
2928            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2929                    UserHandle.getUserId(uid), startResult.pid, uid,
2930                    app.processName, hostingType,
2931                    hostingNameStr != null ? hostingNameStr : "");
2932
2933            if (app.persistent) {
2934                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2935            }
2936
2937            checkTime(startTime, "startProcess: building log message");
2938            StringBuilder buf = mStringBuilder;
2939            buf.setLength(0);
2940            buf.append("Start proc ");
2941            buf.append(app.processName);
2942            if (!isActivityProcess) {
2943                buf.append(" [");
2944                buf.append(entryPoint);
2945                buf.append("]");
2946            }
2947            buf.append(" for ");
2948            buf.append(hostingType);
2949            if (hostingNameStr != null) {
2950                buf.append(" ");
2951                buf.append(hostingNameStr);
2952            }
2953            buf.append(": pid=");
2954            buf.append(startResult.pid);
2955            buf.append(" uid=");
2956            buf.append(uid);
2957            buf.append(" gids={");
2958            if (gids != null) {
2959                for (int gi=0; gi<gids.length; gi++) {
2960                    if (gi != 0) buf.append(", ");
2961                    buf.append(gids[gi]);
2962
2963                }
2964            }
2965            buf.append("}");
2966            if (requiredAbi != null) {
2967                buf.append(" abi=");
2968                buf.append(requiredAbi);
2969            }
2970            Slog.i(TAG, buf.toString());
2971            app.setPid(startResult.pid);
2972            app.usingWrapper = startResult.usingWrapper;
2973            app.removed = false;
2974            app.killed = false;
2975            app.killedByAm = false;
2976            checkTime(startTime, "startProcess: starting to update pids map");
2977            synchronized (mPidsSelfLocked) {
2978                this.mPidsSelfLocked.put(startResult.pid, app);
2979                if (isActivityProcess) {
2980                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2981                    msg.obj = app;
2982                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2983                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2984                }
2985            }
2986            checkTime(startTime, "startProcess: done updating pids map");
2987        } catch (RuntimeException e) {
2988            // XXX do better error recovery.
2989            app.setPid(0);
2990            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
2991            if (app.isolated) {
2992                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
2993            }
2994            Slog.e(TAG, "Failure starting process " + app.processName, e);
2995        }
2996    }
2997
2998    void updateUsageStats(ActivityRecord component, boolean resumed) {
2999        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3000        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3001        if (resumed) {
3002            if (mUsageStatsService != null) {
3003                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3004                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3005            }
3006            synchronized (stats) {
3007                stats.noteActivityResumedLocked(component.app.uid);
3008            }
3009        } else {
3010            if (mUsageStatsService != null) {
3011                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3012                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3013            }
3014            synchronized (stats) {
3015                stats.noteActivityPausedLocked(component.app.uid);
3016            }
3017        }
3018    }
3019
3020    Intent getHomeIntent() {
3021        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3022        intent.setComponent(mTopComponent);
3023        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3024            intent.addCategory(Intent.CATEGORY_HOME);
3025        }
3026        return intent;
3027    }
3028
3029    boolean startHomeActivityLocked(int userId) {
3030        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3031                && mTopAction == null) {
3032            // We are running in factory test mode, but unable to find
3033            // the factory test app, so just sit around displaying the
3034            // error message and don't try to start anything.
3035            return false;
3036        }
3037        Intent intent = getHomeIntent();
3038        ActivityInfo aInfo =
3039            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3040        if (aInfo != null) {
3041            intent.setComponent(new ComponentName(
3042                    aInfo.applicationInfo.packageName, aInfo.name));
3043            // Don't do this if the home app is currently being
3044            // instrumented.
3045            aInfo = new ActivityInfo(aInfo);
3046            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3047            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3048                    aInfo.applicationInfo.uid, true);
3049            if (app == null || app.instrumentationClass == null) {
3050                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3051                mStackSupervisor.startHomeActivity(intent, aInfo);
3052            }
3053        }
3054
3055        return true;
3056    }
3057
3058    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3059        ActivityInfo ai = null;
3060        ComponentName comp = intent.getComponent();
3061        try {
3062            if (comp != null) {
3063                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3064            } else {
3065                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3066                        intent,
3067                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3068                            flags, userId);
3069
3070                if (info != null) {
3071                    ai = info.activityInfo;
3072                }
3073            }
3074        } catch (RemoteException e) {
3075            // ignore
3076        }
3077
3078        return ai;
3079    }
3080
3081    /**
3082     * Starts the "new version setup screen" if appropriate.
3083     */
3084    void startSetupActivityLocked() {
3085        // Only do this once per boot.
3086        if (mCheckedForSetup) {
3087            return;
3088        }
3089
3090        // We will show this screen if the current one is a different
3091        // version than the last one shown, and we are not running in
3092        // low-level factory test mode.
3093        final ContentResolver resolver = mContext.getContentResolver();
3094        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3095                Settings.Global.getInt(resolver,
3096                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3097            mCheckedForSetup = true;
3098
3099            // See if we should be showing the platform update setup UI.
3100            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3101            List<ResolveInfo> ris = mContext.getPackageManager()
3102                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3103
3104            // We don't allow third party apps to replace this.
3105            ResolveInfo ri = null;
3106            for (int i=0; ris != null && i<ris.size(); i++) {
3107                if ((ris.get(i).activityInfo.applicationInfo.flags
3108                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3109                    ri = ris.get(i);
3110                    break;
3111                }
3112            }
3113
3114            if (ri != null) {
3115                String vers = ri.activityInfo.metaData != null
3116                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3117                        : null;
3118                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3119                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3120                            Intent.METADATA_SETUP_VERSION);
3121                }
3122                String lastVers = Settings.Secure.getString(
3123                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3124                if (vers != null && !vers.equals(lastVers)) {
3125                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3126                    intent.setComponent(new ComponentName(
3127                            ri.activityInfo.packageName, ri.activityInfo.name));
3128                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3129                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3130                            null);
3131                }
3132            }
3133        }
3134    }
3135
3136    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3137        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3138    }
3139
3140    void enforceNotIsolatedCaller(String caller) {
3141        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3142            throw new SecurityException("Isolated process not allowed to call " + caller);
3143        }
3144    }
3145
3146    void enforceShellRestriction(String restriction, int userHandle) {
3147        if (Binder.getCallingUid() == Process.SHELL_UID) {
3148            if (userHandle < 0
3149                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3150                throw new SecurityException("Shell does not have permission to access user "
3151                        + userHandle);
3152            }
3153        }
3154    }
3155
3156    @Override
3157    public int getFrontActivityScreenCompatMode() {
3158        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3159        synchronized (this) {
3160            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3161        }
3162    }
3163
3164    @Override
3165    public void setFrontActivityScreenCompatMode(int mode) {
3166        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3167                "setFrontActivityScreenCompatMode");
3168        synchronized (this) {
3169            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3170        }
3171    }
3172
3173    @Override
3174    public int getPackageScreenCompatMode(String packageName) {
3175        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3176        synchronized (this) {
3177            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3178        }
3179    }
3180
3181    @Override
3182    public void setPackageScreenCompatMode(String packageName, int mode) {
3183        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3184                "setPackageScreenCompatMode");
3185        synchronized (this) {
3186            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3187        }
3188    }
3189
3190    @Override
3191    public boolean getPackageAskScreenCompat(String packageName) {
3192        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3193        synchronized (this) {
3194            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3195        }
3196    }
3197
3198    @Override
3199    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3200        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3201                "setPackageAskScreenCompat");
3202        synchronized (this) {
3203            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3204        }
3205    }
3206
3207    private void dispatchProcessesChanged() {
3208        int N;
3209        synchronized (this) {
3210            N = mPendingProcessChanges.size();
3211            if (mActiveProcessChanges.length < N) {
3212                mActiveProcessChanges = new ProcessChangeItem[N];
3213            }
3214            mPendingProcessChanges.toArray(mActiveProcessChanges);
3215            mAvailProcessChanges.addAll(mPendingProcessChanges);
3216            mPendingProcessChanges.clear();
3217            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3218        }
3219
3220        int i = mProcessObservers.beginBroadcast();
3221        while (i > 0) {
3222            i--;
3223            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3224            if (observer != null) {
3225                try {
3226                    for (int j=0; j<N; j++) {
3227                        ProcessChangeItem item = mActiveProcessChanges[j];
3228                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3229                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3230                                    + item.pid + " uid=" + item.uid + ": "
3231                                    + item.foregroundActivities);
3232                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3233                                    item.foregroundActivities);
3234                        }
3235                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3236                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3237                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3238                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3239                        }
3240                    }
3241                } catch (RemoteException e) {
3242                }
3243            }
3244        }
3245        mProcessObservers.finishBroadcast();
3246    }
3247
3248    private void dispatchProcessDied(int pid, int uid) {
3249        int i = mProcessObservers.beginBroadcast();
3250        while (i > 0) {
3251            i--;
3252            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3253            if (observer != null) {
3254                try {
3255                    observer.onProcessDied(pid, uid);
3256                } catch (RemoteException e) {
3257                }
3258            }
3259        }
3260        mProcessObservers.finishBroadcast();
3261    }
3262
3263    @Override
3264    public final int startActivity(IApplicationThread caller, String callingPackage,
3265            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3266            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3267        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3268            resultWho, requestCode, startFlags, profilerInfo, options,
3269            UserHandle.getCallingUserId());
3270    }
3271
3272    @Override
3273    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3274            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3275            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3276        enforceNotIsolatedCaller("startActivity");
3277        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3278                false, ALLOW_FULL_ONLY, "startActivity", null);
3279        // TODO: Switch to user app stacks here.
3280        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3281                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3282                profilerInfo, null, null, options, userId, null, null);
3283    }
3284
3285    @Override
3286    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3287            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3288            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3289
3290        // This is very dangerous -- it allows you to perform a start activity (including
3291        // permission grants) as any app that may launch one of your own activities.  So
3292        // we will only allow this to be done from activities that are part of the core framework,
3293        // and then only when they are running as the system.
3294        final ActivityRecord sourceRecord;
3295        final int targetUid;
3296        final String targetPackage;
3297        synchronized (this) {
3298            if (resultTo == null) {
3299                throw new SecurityException("Must be called from an activity");
3300            }
3301            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3302            if (sourceRecord == null) {
3303                throw new SecurityException("Called with bad activity token: " + resultTo);
3304            }
3305            if (!sourceRecord.info.packageName.equals("android")) {
3306                throw new SecurityException(
3307                        "Must be called from an activity that is declared in the android package");
3308            }
3309            if (sourceRecord.app == null) {
3310                throw new SecurityException("Called without a process attached to activity");
3311            }
3312            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3313                // This is still okay, as long as this activity is running under the
3314                // uid of the original calling activity.
3315                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3316                    throw new SecurityException(
3317                            "Calling activity in uid " + sourceRecord.app.uid
3318                                    + " must be system uid or original calling uid "
3319                                    + sourceRecord.launchedFromUid);
3320                }
3321            }
3322            targetUid = sourceRecord.launchedFromUid;
3323            targetPackage = sourceRecord.launchedFromPackage;
3324        }
3325
3326        if (userId == UserHandle.USER_NULL) {
3327            userId = UserHandle.getUserId(sourceRecord.app.uid);
3328        }
3329
3330        // TODO: Switch to user app stacks here.
3331        try {
3332            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3333                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3334                    null, null, options, userId, null, null);
3335            return ret;
3336        } catch (SecurityException e) {
3337            // XXX need to figure out how to propagate to original app.
3338            // A SecurityException here is generally actually a fault of the original
3339            // calling activity (such as a fairly granting permissions), so propagate it
3340            // back to them.
3341            /*
3342            StringBuilder msg = new StringBuilder();
3343            msg.append("While launching");
3344            msg.append(intent.toString());
3345            msg.append(": ");
3346            msg.append(e.getMessage());
3347            */
3348            throw e;
3349        }
3350    }
3351
3352    @Override
3353    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3354            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3355            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3356        enforceNotIsolatedCaller("startActivityAndWait");
3357        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3358                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3359        WaitResult res = new WaitResult();
3360        // TODO: Switch to user app stacks here.
3361        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3362                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3363                options, userId, null, null);
3364        return res;
3365    }
3366
3367    @Override
3368    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3369            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3370            int startFlags, Configuration config, Bundle options, int userId) {
3371        enforceNotIsolatedCaller("startActivityWithConfig");
3372        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3373                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3374        // TODO: Switch to user app stacks here.
3375        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3376                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3377                null, null, config, options, userId, null, null);
3378        return ret;
3379    }
3380
3381    @Override
3382    public int startActivityIntentSender(IApplicationThread caller,
3383            IntentSender intent, Intent fillInIntent, String resolvedType,
3384            IBinder resultTo, String resultWho, int requestCode,
3385            int flagsMask, int flagsValues, Bundle options) {
3386        enforceNotIsolatedCaller("startActivityIntentSender");
3387        // Refuse possible leaked file descriptors
3388        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3389            throw new IllegalArgumentException("File descriptors passed in Intent");
3390        }
3391
3392        IIntentSender sender = intent.getTarget();
3393        if (!(sender instanceof PendingIntentRecord)) {
3394            throw new IllegalArgumentException("Bad PendingIntent object");
3395        }
3396
3397        PendingIntentRecord pir = (PendingIntentRecord)sender;
3398
3399        synchronized (this) {
3400            // If this is coming from the currently resumed activity, it is
3401            // effectively saying that app switches are allowed at this point.
3402            final ActivityStack stack = getFocusedStack();
3403            if (stack.mResumedActivity != null &&
3404                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3405                mAppSwitchesAllowedTime = 0;
3406            }
3407        }
3408        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3409                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3410        return ret;
3411    }
3412
3413    @Override
3414    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3415            Intent intent, String resolvedType, IVoiceInteractionSession session,
3416            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3417            Bundle options, int userId) {
3418        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3419                != PackageManager.PERMISSION_GRANTED) {
3420            String msg = "Permission Denial: startVoiceActivity() from pid="
3421                    + Binder.getCallingPid()
3422                    + ", uid=" + Binder.getCallingUid()
3423                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3424            Slog.w(TAG, msg);
3425            throw new SecurityException(msg);
3426        }
3427        if (session == null || interactor == null) {
3428            throw new NullPointerException("null session or interactor");
3429        }
3430        userId = handleIncomingUser(callingPid, callingUid, userId,
3431                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3432        // TODO: Switch to user app stacks here.
3433        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3434                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3435                null, options, userId, null, null);
3436    }
3437
3438    @Override
3439    public boolean startNextMatchingActivity(IBinder callingActivity,
3440            Intent intent, Bundle options) {
3441        // Refuse possible leaked file descriptors
3442        if (intent != null && intent.hasFileDescriptors() == true) {
3443            throw new IllegalArgumentException("File descriptors passed in Intent");
3444        }
3445
3446        synchronized (this) {
3447            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3448            if (r == null) {
3449                ActivityOptions.abort(options);
3450                return false;
3451            }
3452            if (r.app == null || r.app.thread == null) {
3453                // The caller is not running...  d'oh!
3454                ActivityOptions.abort(options);
3455                return false;
3456            }
3457            intent = new Intent(intent);
3458            // The caller is not allowed to change the data.
3459            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3460            // And we are resetting to find the next component...
3461            intent.setComponent(null);
3462
3463            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3464
3465            ActivityInfo aInfo = null;
3466            try {
3467                List<ResolveInfo> resolves =
3468                    AppGlobals.getPackageManager().queryIntentActivities(
3469                            intent, r.resolvedType,
3470                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3471                            UserHandle.getCallingUserId());
3472
3473                // Look for the original activity in the list...
3474                final int N = resolves != null ? resolves.size() : 0;
3475                for (int i=0; i<N; i++) {
3476                    ResolveInfo rInfo = resolves.get(i);
3477                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3478                            && rInfo.activityInfo.name.equals(r.info.name)) {
3479                        // We found the current one...  the next matching is
3480                        // after it.
3481                        i++;
3482                        if (i<N) {
3483                            aInfo = resolves.get(i).activityInfo;
3484                        }
3485                        if (debug) {
3486                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3487                                    + "/" + r.info.name);
3488                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3489                                    + "/" + aInfo.name);
3490                        }
3491                        break;
3492                    }
3493                }
3494            } catch (RemoteException e) {
3495            }
3496
3497            if (aInfo == null) {
3498                // Nobody who is next!
3499                ActivityOptions.abort(options);
3500                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3501                return false;
3502            }
3503
3504            intent.setComponent(new ComponentName(
3505                    aInfo.applicationInfo.packageName, aInfo.name));
3506            intent.setFlags(intent.getFlags()&~(
3507                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3508                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3509                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3510                    Intent.FLAG_ACTIVITY_NEW_TASK));
3511
3512            // Okay now we need to start the new activity, replacing the
3513            // currently running activity.  This is a little tricky because
3514            // we want to start the new one as if the current one is finished,
3515            // but not finish the current one first so that there is no flicker.
3516            // And thus...
3517            final boolean wasFinishing = r.finishing;
3518            r.finishing = true;
3519
3520            // Propagate reply information over to the new activity.
3521            final ActivityRecord resultTo = r.resultTo;
3522            final String resultWho = r.resultWho;
3523            final int requestCode = r.requestCode;
3524            r.resultTo = null;
3525            if (resultTo != null) {
3526                resultTo.removeResultsLocked(r, resultWho, requestCode);
3527            }
3528
3529            final long origId = Binder.clearCallingIdentity();
3530            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3531                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3532                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3533                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3534            Binder.restoreCallingIdentity(origId);
3535
3536            r.finishing = wasFinishing;
3537            if (res != ActivityManager.START_SUCCESS) {
3538                return false;
3539            }
3540            return true;
3541        }
3542    }
3543
3544    @Override
3545    public final int startActivityFromRecents(int taskId, Bundle options) {
3546        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3547            String msg = "Permission Denial: startActivityFromRecents called without " +
3548                    START_TASKS_FROM_RECENTS;
3549            Slog.w(TAG, msg);
3550            throw new SecurityException(msg);
3551        }
3552        return startActivityFromRecentsInner(taskId, options);
3553    }
3554
3555    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3556        final TaskRecord task;
3557        final int callingUid;
3558        final String callingPackage;
3559        final Intent intent;
3560        final int userId;
3561        synchronized (this) {
3562            task = recentTaskForIdLocked(taskId);
3563            if (task == null) {
3564                throw new IllegalArgumentException("Task " + taskId + " not found.");
3565            }
3566            callingUid = task.mCallingUid;
3567            callingPackage = task.mCallingPackage;
3568            intent = task.intent;
3569            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3570            userId = task.userId;
3571        }
3572        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3573                options, userId, null, task);
3574    }
3575
3576    final int startActivityInPackage(int uid, String callingPackage,
3577            Intent intent, String resolvedType, IBinder resultTo,
3578            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3579            IActivityContainer container, TaskRecord inTask) {
3580
3581        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3582                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3583
3584        // TODO: Switch to user app stacks here.
3585        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3586                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3587                null, null, null, options, userId, container, inTask);
3588        return ret;
3589    }
3590
3591    @Override
3592    public final int startActivities(IApplicationThread caller, String callingPackage,
3593            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3594            int userId) {
3595        enforceNotIsolatedCaller("startActivities");
3596        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3597                false, ALLOW_FULL_ONLY, "startActivity", null);
3598        // TODO: Switch to user app stacks here.
3599        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3600                resolvedTypes, resultTo, options, userId);
3601        return ret;
3602    }
3603
3604    final int startActivitiesInPackage(int uid, String callingPackage,
3605            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3606            Bundle options, int userId) {
3607
3608        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3609                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3610        // TODO: Switch to user app stacks here.
3611        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3612                resultTo, options, userId);
3613        return ret;
3614    }
3615
3616    //explicitly remove thd old information in mRecentTasks when removing existing user.
3617    private void removeRecentTasksForUserLocked(int userId) {
3618        if(userId <= 0) {
3619            Slog.i(TAG, "Can't remove recent task on user " + userId);
3620            return;
3621        }
3622
3623        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3624            TaskRecord tr = mRecentTasks.get(i);
3625            if (tr.userId == userId) {
3626                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3627                        + " when finishing user" + userId);
3628                mRecentTasks.remove(i);
3629                tr.removedFromRecents(mTaskPersister);
3630            }
3631        }
3632
3633        // Remove tasks from persistent storage.
3634        mTaskPersister.wakeup(null, true);
3635    }
3636
3637    // Sort by taskId
3638    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3639        @Override
3640        public int compare(TaskRecord lhs, TaskRecord rhs) {
3641            return rhs.taskId - lhs.taskId;
3642        }
3643    };
3644
3645    // Extract the affiliates of the chain containing mRecentTasks[start].
3646    private int processNextAffiliateChain(int start) {
3647        final TaskRecord startTask = mRecentTasks.get(start);
3648        final int affiliateId = startTask.mAffiliatedTaskId;
3649
3650        // Quick identification of isolated tasks. I.e. those not launched behind.
3651        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3652                startTask.mNextAffiliate == null) {
3653            // There is still a slim chance that there are other tasks that point to this task
3654            // and that the chain is so messed up that this task no longer points to them but
3655            // the gain of this optimization outweighs the risk.
3656            startTask.inRecents = true;
3657            return start + 1;
3658        }
3659
3660        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3661        mTmpRecents.clear();
3662        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3663            final TaskRecord task = mRecentTasks.get(i);
3664            if (task.mAffiliatedTaskId == affiliateId) {
3665                mRecentTasks.remove(i);
3666                mTmpRecents.add(task);
3667            }
3668        }
3669
3670        // Sort them all by taskId. That is the order they were create in and that order will
3671        // always be correct.
3672        Collections.sort(mTmpRecents, mTaskRecordComparator);
3673
3674        // Go through and fix up the linked list.
3675        // The first one is the end of the chain and has no next.
3676        final TaskRecord first = mTmpRecents.get(0);
3677        first.inRecents = true;
3678        if (first.mNextAffiliate != null) {
3679            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3680            first.setNextAffiliate(null);
3681            mTaskPersister.wakeup(first, false);
3682        }
3683        // Everything in the middle is doubly linked from next to prev.
3684        final int tmpSize = mTmpRecents.size();
3685        for (int i = 0; i < tmpSize - 1; ++i) {
3686            final TaskRecord next = mTmpRecents.get(i);
3687            final TaskRecord prev = mTmpRecents.get(i + 1);
3688            if (next.mPrevAffiliate != prev) {
3689                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3690                        " setting prev=" + prev);
3691                next.setPrevAffiliate(prev);
3692                mTaskPersister.wakeup(next, false);
3693            }
3694            if (prev.mNextAffiliate != next) {
3695                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3696                        " setting next=" + next);
3697                prev.setNextAffiliate(next);
3698                mTaskPersister.wakeup(prev, false);
3699            }
3700            prev.inRecents = true;
3701        }
3702        // The last one is the beginning of the list and has no prev.
3703        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3704        if (last.mPrevAffiliate != null) {
3705            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3706            last.setPrevAffiliate(null);
3707            mTaskPersister.wakeup(last, false);
3708        }
3709
3710        // Insert the group back into mRecentTasks at start.
3711        mRecentTasks.addAll(start, mTmpRecents);
3712
3713        // Let the caller know where we left off.
3714        return start + tmpSize;
3715    }
3716
3717    /**
3718     * Update the recent tasks lists: make sure tasks should still be here (their
3719     * applications / activities still exist), update their availability, fixup ordering
3720     * of affiliations.
3721     */
3722    void cleanupRecentTasksLocked(int userId) {
3723        if (mRecentTasks == null) {
3724            // Happens when called from the packagemanager broadcast before boot.
3725            return;
3726        }
3727
3728        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3729        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3730        final IPackageManager pm = AppGlobals.getPackageManager();
3731        final ActivityInfo dummyAct = new ActivityInfo();
3732        final ApplicationInfo dummyApp = new ApplicationInfo();
3733
3734        int N = mRecentTasks.size();
3735
3736        int[] users = userId == UserHandle.USER_ALL
3737                ? getUsersLocked() : new int[] { userId };
3738        for (int user : users) {
3739            for (int i = 0; i < N; i++) {
3740                TaskRecord task = mRecentTasks.get(i);
3741                if (task.userId != user) {
3742                    // Only look at tasks for the user ID of interest.
3743                    continue;
3744                }
3745                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3746                    // This situation is broken, and we should just get rid of it now.
3747                    mRecentTasks.remove(i);
3748                    task.removedFromRecents(mTaskPersister);
3749                    i--;
3750                    N--;
3751                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3752                    continue;
3753                }
3754                // Check whether this activity is currently available.
3755                if (task.realActivity != null) {
3756                    ActivityInfo ai = availActCache.get(task.realActivity);
3757                    if (ai == null) {
3758                        try {
3759                            ai = pm.getActivityInfo(task.realActivity,
3760                                    PackageManager.GET_UNINSTALLED_PACKAGES
3761                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3762                        } catch (RemoteException e) {
3763                            // Will never happen.
3764                            continue;
3765                        }
3766                        if (ai == null) {
3767                            ai = dummyAct;
3768                        }
3769                        availActCache.put(task.realActivity, ai);
3770                    }
3771                    if (ai == dummyAct) {
3772                        // This could be either because the activity no longer exists, or the
3773                        // app is temporarily gone.  For the former we want to remove the recents
3774                        // entry; for the latter we want to mark it as unavailable.
3775                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3776                        if (app == null) {
3777                            try {
3778                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3779                                        PackageManager.GET_UNINSTALLED_PACKAGES
3780                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3781                            } catch (RemoteException e) {
3782                                // Will never happen.
3783                                continue;
3784                            }
3785                            if (app == null) {
3786                                app = dummyApp;
3787                            }
3788                            availAppCache.put(task.realActivity.getPackageName(), app);
3789                        }
3790                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3791                            // Doesn't exist any more!  Good-bye.
3792                            mRecentTasks.remove(i);
3793                            task.removedFromRecents(mTaskPersister);
3794                            i--;
3795                            N--;
3796                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3797                            continue;
3798                        } else {
3799                            // Otherwise just not available for now.
3800                            if (task.isAvailable) {
3801                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3802                                        + task);
3803                            }
3804                            task.isAvailable = false;
3805                        }
3806                    } else {
3807                        if (!ai.enabled || !ai.applicationInfo.enabled
3808                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3809                            if (task.isAvailable) {
3810                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3811                                        + task + " (enabled=" + ai.enabled + "/"
3812                                        + ai.applicationInfo.enabled +  " flags="
3813                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3814                            }
3815                            task.isAvailable = false;
3816                        } else {
3817                            if (!task.isAvailable) {
3818                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3819                                        + task);
3820                            }
3821                            task.isAvailable = true;
3822                        }
3823                    }
3824                }
3825            }
3826        }
3827
3828        // Verify the affiliate chain for each task.
3829        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
3830        }
3831
3832        mTmpRecents.clear();
3833        // mRecentTasks is now in sorted, affiliated order.
3834    }
3835
3836    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3837        int N = mRecentTasks.size();
3838        TaskRecord top = task;
3839        int topIndex = taskIndex;
3840        while (top.mNextAffiliate != null && topIndex > 0) {
3841            top = top.mNextAffiliate;
3842            topIndex--;
3843        }
3844        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3845                + topIndex + " from intial " + taskIndex);
3846        // Find the end of the chain, doing a sanity check along the way.
3847        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3848        int endIndex = topIndex;
3849        TaskRecord prev = top;
3850        while (endIndex < N) {
3851            TaskRecord cur = mRecentTasks.get(endIndex);
3852            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3853                    + endIndex + " " + cur);
3854            if (cur == top) {
3855                // Verify start of the chain.
3856                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3857                    Slog.wtf(TAG, "Bad chain @" + endIndex
3858                            + ": first task has next affiliate: " + prev);
3859                    sane = false;
3860                    break;
3861                }
3862            } else {
3863                // Verify middle of the chain's next points back to the one before.
3864                if (cur.mNextAffiliate != prev
3865                        || cur.mNextAffiliateTaskId != prev.taskId) {
3866                    Slog.wtf(TAG, "Bad chain @" + endIndex
3867                            + ": middle task " + cur + " @" + endIndex
3868                            + " has bad next affiliate "
3869                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3870                            + ", expected " + prev);
3871                    sane = false;
3872                    break;
3873                }
3874            }
3875            if (cur.mPrevAffiliateTaskId == -1) {
3876                // Chain ends here.
3877                if (cur.mPrevAffiliate != null) {
3878                    Slog.wtf(TAG, "Bad chain @" + endIndex
3879                            + ": last task " + cur + " has previous affiliate "
3880                            + cur.mPrevAffiliate);
3881                    sane = false;
3882                }
3883                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3884                break;
3885            } else {
3886                // Verify middle of the chain's prev points to a valid item.
3887                if (cur.mPrevAffiliate == null) {
3888                    Slog.wtf(TAG, "Bad chain @" + endIndex
3889                            + ": task " + cur + " has previous affiliate "
3890                            + cur.mPrevAffiliate + " but should be id "
3891                            + cur.mPrevAffiliate);
3892                    sane = false;
3893                    break;
3894                }
3895            }
3896            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3897                Slog.wtf(TAG, "Bad chain @" + endIndex
3898                        + ": task " + cur + " has affiliated id "
3899                        + cur.mAffiliatedTaskId + " but should be "
3900                        + task.mAffiliatedTaskId);
3901                sane = false;
3902                break;
3903            }
3904            prev = cur;
3905            endIndex++;
3906            if (endIndex >= N) {
3907                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3908                        + ": last task " + prev);
3909                sane = false;
3910                break;
3911            }
3912        }
3913        if (sane) {
3914            if (endIndex < taskIndex) {
3915                Slog.wtf(TAG, "Bad chain @" + endIndex
3916                        + ": did not extend to task " + task + " @" + taskIndex);
3917                sane = false;
3918            }
3919        }
3920        if (sane) {
3921            // All looks good, we can just move all of the affiliated tasks
3922            // to the top.
3923            for (int i=topIndex; i<=endIndex; i++) {
3924                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3925                        + " from " + i + " to " + (i-topIndex));
3926                TaskRecord cur = mRecentTasks.remove(i);
3927                mRecentTasks.add(i-topIndex, cur);
3928            }
3929            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3930                    + " to " + endIndex);
3931            return true;
3932        }
3933
3934        // Whoops, couldn't do it.
3935        return false;
3936    }
3937
3938    final void addRecentTaskLocked(TaskRecord task) {
3939        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
3940                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
3941
3942        int N = mRecentTasks.size();
3943        // Quick case: check if the top-most recent task is the same.
3944        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
3945            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
3946            return;
3947        }
3948        // Another quick case: check if this is part of a set of affiliated
3949        // tasks that are at the top.
3950        if (isAffiliated && N > 0 && task.inRecents
3951                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
3952            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
3953                    + " at top when adding " + task);
3954            return;
3955        }
3956        // Another quick case: never add voice sessions.
3957        if (task.voiceSession != null) {
3958            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
3959            return;
3960        }
3961
3962        boolean needAffiliationFix = false;
3963
3964        // Slightly less quick case: the task is already in recents, so all we need
3965        // to do is move it.
3966        if (task.inRecents) {
3967            int taskIndex = mRecentTasks.indexOf(task);
3968            if (taskIndex >= 0) {
3969                if (!isAffiliated) {
3970                    // Simple case: this is not an affiliated task, so we just move it to the front.
3971                    mRecentTasks.remove(taskIndex);
3972                    mRecentTasks.add(0, task);
3973                    notifyTaskPersisterLocked(task, false);
3974                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
3975                            + " from " + taskIndex);
3976                    return;
3977                } else {
3978                    // More complicated: need to keep all affiliated tasks together.
3979                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
3980                        // All went well.
3981                        return;
3982                    }
3983
3984                    // Uh oh...  something bad in the affiliation chain, try to rebuild
3985                    // everything and then go through our general path of adding a new task.
3986                    needAffiliationFix = true;
3987                }
3988            } else {
3989                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
3990                needAffiliationFix = true;
3991            }
3992        }
3993
3994        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
3995        trimRecentsForTask(task, true);
3996
3997        N = mRecentTasks.size();
3998        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
3999            final TaskRecord tr = mRecentTasks.remove(N - 1);
4000            tr.removedFromRecents(mTaskPersister);
4001            N--;
4002        }
4003        task.inRecents = true;
4004        if (!isAffiliated || needAffiliationFix) {
4005            // If this is a simple non-affiliated task, or we had some failure trying to
4006            // handle it as part of an affilated task, then just place it at the top.
4007            mRecentTasks.add(0, task);
4008        } else if (isAffiliated) {
4009            // If this is a new affiliated task, then move all of the affiliated tasks
4010            // to the front and insert this new one.
4011            TaskRecord other = task.mNextAffiliate;
4012            if (other == null) {
4013                other = task.mPrevAffiliate;
4014            }
4015            if (other != null) {
4016                int otherIndex = mRecentTasks.indexOf(other);
4017                if (otherIndex >= 0) {
4018                    // Insert new task at appropriate location.
4019                    int taskIndex;
4020                    if (other == task.mNextAffiliate) {
4021                        // We found the index of our next affiliation, which is who is
4022                        // before us in the list, so add after that point.
4023                        taskIndex = otherIndex+1;
4024                    } else {
4025                        // We found the index of our previous affiliation, which is who is
4026                        // after us in the list, so add at their position.
4027                        taskIndex = otherIndex;
4028                    }
4029                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4030                            + taskIndex + ": " + task);
4031                    mRecentTasks.add(taskIndex, task);
4032
4033                    // Now move everything to the front.
4034                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4035                        // All went well.
4036                        return;
4037                    }
4038
4039                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4040                    // everything and then go through our general path of adding a new task.
4041                    needAffiliationFix = true;
4042                } else {
4043                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4044                            + other);
4045                    needAffiliationFix = true;
4046                }
4047            } else {
4048                if (DEBUG_RECENTS) Slog.d(TAG,
4049                        "addRecent: adding affiliated task without next/prev:" + task);
4050                needAffiliationFix = true;
4051            }
4052        }
4053        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4054
4055        if (needAffiliationFix) {
4056            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4057            cleanupRecentTasksLocked(task.userId);
4058        }
4059    }
4060
4061    /**
4062     * If needed, remove oldest existing entries in recents that are for the same kind
4063     * of task as the given one.
4064     */
4065    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4066        int N = mRecentTasks.size();
4067        final Intent intent = task.intent;
4068        final boolean document = intent != null && intent.isDocument();
4069
4070        int maxRecents = task.maxRecents - 1;
4071        for (int i=0; i<N; i++) {
4072            final TaskRecord tr = mRecentTasks.get(i);
4073            if (task != tr) {
4074                if (task.userId != tr.userId) {
4075                    continue;
4076                }
4077                if (i > MAX_RECENT_BITMAPS) {
4078                    tr.freeLastThumbnail();
4079                }
4080                final Intent trIntent = tr.intent;
4081                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4082                    (intent == null || !intent.filterEquals(trIntent))) {
4083                    continue;
4084                }
4085                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4086                if (document && trIsDocument) {
4087                    // These are the same document activity (not necessarily the same doc).
4088                    if (maxRecents > 0) {
4089                        --maxRecents;
4090                        continue;
4091                    }
4092                    // Hit the maximum number of documents for this task. Fall through
4093                    // and remove this document from recents.
4094                } else if (document || trIsDocument) {
4095                    // Only one of these is a document. Not the droid we're looking for.
4096                    continue;
4097                }
4098            }
4099
4100            if (!doTrim) {
4101                // If the caller is not actually asking for a trim, just tell them we reached
4102                // a point where the trim would happen.
4103                return i;
4104            }
4105
4106            // Either task and tr are the same or, their affinities match or their intents match
4107            // and neither of them is a document, or they are documents using the same activity
4108            // and their maxRecents has been reached.
4109            tr.disposeThumbnail();
4110            mRecentTasks.remove(i);
4111            if (task != tr) {
4112                tr.removedFromRecents(mTaskPersister);
4113            }
4114            i--;
4115            N--;
4116            if (task.intent == null) {
4117                // If the new recent task we are adding is not fully
4118                // specified, then replace it with the existing recent task.
4119                task = tr;
4120            }
4121            notifyTaskPersisterLocked(tr, false);
4122        }
4123
4124        return -1;
4125    }
4126
4127    @Override
4128    public void reportActivityFullyDrawn(IBinder token) {
4129        synchronized (this) {
4130            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4131            if (r == null) {
4132                return;
4133            }
4134            r.reportFullyDrawnLocked();
4135        }
4136    }
4137
4138    @Override
4139    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4140        synchronized (this) {
4141            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4142            if (r == null) {
4143                return;
4144            }
4145            final long origId = Binder.clearCallingIdentity();
4146            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4147            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4148                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4149            if (config != null) {
4150                r.frozenBeforeDestroy = true;
4151                if (!updateConfigurationLocked(config, r, false, false)) {
4152                    mStackSupervisor.resumeTopActivitiesLocked();
4153                }
4154            }
4155            Binder.restoreCallingIdentity(origId);
4156        }
4157    }
4158
4159    @Override
4160    public int getRequestedOrientation(IBinder token) {
4161        synchronized (this) {
4162            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4163            if (r == null) {
4164                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4165            }
4166            return mWindowManager.getAppOrientation(r.appToken);
4167        }
4168    }
4169
4170    /**
4171     * This is the internal entry point for handling Activity.finish().
4172     *
4173     * @param token The Binder token referencing the Activity we want to finish.
4174     * @param resultCode Result code, if any, from this Activity.
4175     * @param resultData Result data (Intent), if any, from this Activity.
4176     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4177     *            the root Activity in the task.
4178     *
4179     * @return Returns true if the activity successfully finished, or false if it is still running.
4180     */
4181    @Override
4182    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4183            boolean finishTask) {
4184        // Refuse possible leaked file descriptors
4185        if (resultData != null && resultData.hasFileDescriptors() == true) {
4186            throw new IllegalArgumentException("File descriptors passed in Intent");
4187        }
4188
4189        synchronized(this) {
4190            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4191            if (r == null) {
4192                return true;
4193            }
4194            // Keep track of the root activity of the task before we finish it
4195            TaskRecord tr = r.task;
4196            ActivityRecord rootR = tr.getRootActivity();
4197            if (rootR == null) {
4198                Slog.w(TAG, "Finishing task with all activities already finished");
4199            }
4200            // Do not allow task to finish in Lock Task mode.
4201            if (tr == mStackSupervisor.mLockTaskModeTask) {
4202                if (rootR == r) {
4203                    Slog.i(TAG, "Not finishing task in lock task mode");
4204                    mStackSupervisor.showLockTaskToast();
4205                    return false;
4206                }
4207            }
4208            if (mController != null) {
4209                // Find the first activity that is not finishing.
4210                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4211                if (next != null) {
4212                    // ask watcher if this is allowed
4213                    boolean resumeOK = true;
4214                    try {
4215                        resumeOK = mController.activityResuming(next.packageName);
4216                    } catch (RemoteException e) {
4217                        mController = null;
4218                        Watchdog.getInstance().setActivityController(null);
4219                    }
4220
4221                    if (!resumeOK) {
4222                        Slog.i(TAG, "Not finishing activity because controller resumed");
4223                        return false;
4224                    }
4225                }
4226            }
4227            final long origId = Binder.clearCallingIdentity();
4228            try {
4229                boolean res;
4230                if (finishTask && r == rootR) {
4231                    // If requested, remove the task that is associated to this activity only if it
4232                    // was the root activity in the task. The result code and data is ignored
4233                    // because we don't support returning them across task boundaries.
4234                    res = removeTaskByIdLocked(tr.taskId, false);
4235                    if (!res) {
4236                        Slog.i(TAG, "Removing task failed to finish activity");
4237                    }
4238                } else {
4239                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4240                            resultData, "app-request", true);
4241                    if (!res) {
4242                        Slog.i(TAG, "Failed to finish by app-request");
4243                    }
4244                }
4245                return res;
4246            } finally {
4247                Binder.restoreCallingIdentity(origId);
4248            }
4249        }
4250    }
4251
4252    @Override
4253    public final void finishHeavyWeightApp() {
4254        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4255                != PackageManager.PERMISSION_GRANTED) {
4256            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4257                    + Binder.getCallingPid()
4258                    + ", uid=" + Binder.getCallingUid()
4259                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4260            Slog.w(TAG, msg);
4261            throw new SecurityException(msg);
4262        }
4263
4264        synchronized(this) {
4265            if (mHeavyWeightProcess == null) {
4266                return;
4267            }
4268
4269            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4270                    mHeavyWeightProcess.activities);
4271            for (int i=0; i<activities.size(); i++) {
4272                ActivityRecord r = activities.get(i);
4273                if (!r.finishing) {
4274                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4275                            null, "finish-heavy", true);
4276                }
4277            }
4278
4279            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4280                    mHeavyWeightProcess.userId, 0));
4281            mHeavyWeightProcess = null;
4282        }
4283    }
4284
4285    @Override
4286    public void crashApplication(int uid, int initialPid, String packageName,
4287            String message) {
4288        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4289                != PackageManager.PERMISSION_GRANTED) {
4290            String msg = "Permission Denial: crashApplication() from pid="
4291                    + Binder.getCallingPid()
4292                    + ", uid=" + Binder.getCallingUid()
4293                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4294            Slog.w(TAG, msg);
4295            throw new SecurityException(msg);
4296        }
4297
4298        synchronized(this) {
4299            ProcessRecord proc = null;
4300
4301            // Figure out which process to kill.  We don't trust that initialPid
4302            // still has any relation to current pids, so must scan through the
4303            // list.
4304            synchronized (mPidsSelfLocked) {
4305                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4306                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4307                    if (p.uid != uid) {
4308                        continue;
4309                    }
4310                    if (p.pid == initialPid) {
4311                        proc = p;
4312                        break;
4313                    }
4314                    if (p.pkgList.containsKey(packageName)) {
4315                        proc = p;
4316                    }
4317                }
4318            }
4319
4320            if (proc == null) {
4321                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4322                        + " initialPid=" + initialPid
4323                        + " packageName=" + packageName);
4324                return;
4325            }
4326
4327            if (proc.thread != null) {
4328                if (proc.pid == Process.myPid()) {
4329                    Log.w(TAG, "crashApplication: trying to crash self!");
4330                    return;
4331                }
4332                long ident = Binder.clearCallingIdentity();
4333                try {
4334                    proc.thread.scheduleCrash(message);
4335                } catch (RemoteException e) {
4336                }
4337                Binder.restoreCallingIdentity(ident);
4338            }
4339        }
4340    }
4341
4342    @Override
4343    public final void finishSubActivity(IBinder token, String resultWho,
4344            int requestCode) {
4345        synchronized(this) {
4346            final long origId = Binder.clearCallingIdentity();
4347            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4348            if (r != null) {
4349                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4350            }
4351            Binder.restoreCallingIdentity(origId);
4352        }
4353    }
4354
4355    @Override
4356    public boolean finishActivityAffinity(IBinder token) {
4357        synchronized(this) {
4358            final long origId = Binder.clearCallingIdentity();
4359            try {
4360                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4361
4362                ActivityRecord rootR = r.task.getRootActivity();
4363                // Do not allow task to finish in Lock Task mode.
4364                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4365                    if (rootR == r) {
4366                        mStackSupervisor.showLockTaskToast();
4367                        return false;
4368                    }
4369                }
4370                boolean res = false;
4371                if (r != null) {
4372                    res = r.task.stack.finishActivityAffinityLocked(r);
4373                }
4374                return res;
4375            } finally {
4376                Binder.restoreCallingIdentity(origId);
4377            }
4378        }
4379    }
4380
4381    @Override
4382    public void finishVoiceTask(IVoiceInteractionSession session) {
4383        synchronized(this) {
4384            final long origId = Binder.clearCallingIdentity();
4385            try {
4386                mStackSupervisor.finishVoiceTask(session);
4387            } finally {
4388                Binder.restoreCallingIdentity(origId);
4389            }
4390        }
4391
4392    }
4393
4394    @Override
4395    public boolean releaseActivityInstance(IBinder token) {
4396        synchronized(this) {
4397            final long origId = Binder.clearCallingIdentity();
4398            try {
4399                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4400                if (r.task == null || r.task.stack == null) {
4401                    return false;
4402                }
4403                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4404            } finally {
4405                Binder.restoreCallingIdentity(origId);
4406            }
4407        }
4408    }
4409
4410    @Override
4411    public void releaseSomeActivities(IApplicationThread appInt) {
4412        synchronized(this) {
4413            final long origId = Binder.clearCallingIdentity();
4414            try {
4415                ProcessRecord app = getRecordForAppLocked(appInt);
4416                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4417            } finally {
4418                Binder.restoreCallingIdentity(origId);
4419            }
4420        }
4421    }
4422
4423    @Override
4424    public boolean willActivityBeVisible(IBinder token) {
4425        synchronized(this) {
4426            ActivityStack stack = ActivityRecord.getStackLocked(token);
4427            if (stack != null) {
4428                return stack.willActivityBeVisibleLocked(token);
4429            }
4430            return false;
4431        }
4432    }
4433
4434    @Override
4435    public void overridePendingTransition(IBinder token, String packageName,
4436            int enterAnim, int exitAnim) {
4437        synchronized(this) {
4438            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4439            if (self == null) {
4440                return;
4441            }
4442
4443            final long origId = Binder.clearCallingIdentity();
4444
4445            if (self.state == ActivityState.RESUMED
4446                    || self.state == ActivityState.PAUSING) {
4447                mWindowManager.overridePendingAppTransition(packageName,
4448                        enterAnim, exitAnim, null);
4449            }
4450
4451            Binder.restoreCallingIdentity(origId);
4452        }
4453    }
4454
4455    /**
4456     * Main function for removing an existing process from the activity manager
4457     * as a result of that process going away.  Clears out all connections
4458     * to the process.
4459     */
4460    private final void handleAppDiedLocked(ProcessRecord app,
4461            boolean restarting, boolean allowRestart) {
4462        int pid = app.pid;
4463        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4464        if (!kept && !restarting) {
4465            removeLruProcessLocked(app);
4466            if (pid > 0) {
4467                ProcessList.remove(pid);
4468            }
4469        }
4470
4471        if (mProfileProc == app) {
4472            clearProfilerLocked();
4473        }
4474
4475        // Remove this application's activities from active lists.
4476        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4477
4478        app.activities.clear();
4479
4480        if (app.instrumentationClass != null) {
4481            Slog.w(TAG, "Crash of app " + app.processName
4482                  + " running instrumentation " + app.instrumentationClass);
4483            Bundle info = new Bundle();
4484            info.putString("shortMsg", "Process crashed.");
4485            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4486        }
4487
4488        if (!restarting) {
4489            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4490                // If there was nothing to resume, and we are not already
4491                // restarting this process, but there is a visible activity that
4492                // is hosted by the process...  then make sure all visible
4493                // activities are running, taking care of restarting this
4494                // process.
4495                if (hasVisibleActivities) {
4496                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4497                }
4498            }
4499        }
4500    }
4501
4502    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4503        IBinder threadBinder = thread.asBinder();
4504        // Find the application record.
4505        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4506            ProcessRecord rec = mLruProcesses.get(i);
4507            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4508                return i;
4509            }
4510        }
4511        return -1;
4512    }
4513
4514    final ProcessRecord getRecordForAppLocked(
4515            IApplicationThread thread) {
4516        if (thread == null) {
4517            return null;
4518        }
4519
4520        int appIndex = getLRURecordIndexForAppLocked(thread);
4521        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4522    }
4523
4524    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4525        // If there are no longer any background processes running,
4526        // and the app that died was not running instrumentation,
4527        // then tell everyone we are now low on memory.
4528        boolean haveBg = false;
4529        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4530            ProcessRecord rec = mLruProcesses.get(i);
4531            if (rec.thread != null
4532                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4533                haveBg = true;
4534                break;
4535            }
4536        }
4537
4538        if (!haveBg) {
4539            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4540            if (doReport) {
4541                long now = SystemClock.uptimeMillis();
4542                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4543                    doReport = false;
4544                } else {
4545                    mLastMemUsageReportTime = now;
4546                }
4547            }
4548            final ArrayList<ProcessMemInfo> memInfos
4549                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4550            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4551            long now = SystemClock.uptimeMillis();
4552            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4553                ProcessRecord rec = mLruProcesses.get(i);
4554                if (rec == dyingProc || rec.thread == null) {
4555                    continue;
4556                }
4557                if (doReport) {
4558                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4559                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4560                }
4561                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4562                    // The low memory report is overriding any current
4563                    // state for a GC request.  Make sure to do
4564                    // heavy/important/visible/foreground processes first.
4565                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4566                        rec.lastRequestedGc = 0;
4567                    } else {
4568                        rec.lastRequestedGc = rec.lastLowMemory;
4569                    }
4570                    rec.reportLowMemory = true;
4571                    rec.lastLowMemory = now;
4572                    mProcessesToGc.remove(rec);
4573                    addProcessToGcListLocked(rec);
4574                }
4575            }
4576            if (doReport) {
4577                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4578                mHandler.sendMessage(msg);
4579            }
4580            scheduleAppGcsLocked();
4581        }
4582    }
4583
4584    final void appDiedLocked(ProcessRecord app) {
4585       appDiedLocked(app, app.pid, app.thread);
4586    }
4587
4588    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4589        // First check if this ProcessRecord is actually active for the pid.
4590        synchronized (mPidsSelfLocked) {
4591            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4592            if (curProc != app) {
4593                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4594                return;
4595            }
4596        }
4597
4598        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4599        synchronized (stats) {
4600            stats.noteProcessDiedLocked(app.info.uid, pid);
4601        }
4602
4603        Process.killProcessQuiet(pid);
4604        Process.killProcessGroup(app.info.uid, pid);
4605        app.killed = true;
4606
4607        // Clean up already done if the process has been re-started.
4608        if (app.pid == pid && app.thread != null &&
4609                app.thread.asBinder() == thread.asBinder()) {
4610            boolean doLowMem = app.instrumentationClass == null;
4611            boolean doOomAdj = doLowMem;
4612            if (!app.killedByAm) {
4613                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4614                        + ") has died");
4615                mAllowLowerMemLevel = true;
4616            } else {
4617                // Note that we always want to do oom adj to update our state with the
4618                // new number of procs.
4619                mAllowLowerMemLevel = false;
4620                doLowMem = false;
4621            }
4622            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4623            if (DEBUG_CLEANUP) Slog.v(
4624                TAG, "Dying app: " + app + ", pid: " + pid
4625                + ", thread: " + thread.asBinder());
4626            handleAppDiedLocked(app, false, true);
4627
4628            if (doOomAdj) {
4629                updateOomAdjLocked();
4630            }
4631            if (doLowMem) {
4632                doLowMemReportIfNeededLocked(app);
4633            }
4634        } else if (app.pid != pid) {
4635            // A new process has already been started.
4636            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4637                    + ") has died and restarted (pid " + app.pid + ").");
4638            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4639        } else if (DEBUG_PROCESSES) {
4640            Slog.d(TAG, "Received spurious death notification for thread "
4641                    + thread.asBinder());
4642        }
4643    }
4644
4645    /**
4646     * If a stack trace dump file is configured, dump process stack traces.
4647     * @param clearTraces causes the dump file to be erased prior to the new
4648     *    traces being written, if true; when false, the new traces will be
4649     *    appended to any existing file content.
4650     * @param firstPids of dalvik VM processes to dump stack traces for first
4651     * @param lastPids of dalvik VM processes to dump stack traces for last
4652     * @param nativeProcs optional list of native process names to dump stack crawls
4653     * @return file containing stack traces, or null if no dump file is configured
4654     */
4655    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4656            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4657        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4658        if (tracesPath == null || tracesPath.length() == 0) {
4659            return null;
4660        }
4661
4662        File tracesFile = new File(tracesPath);
4663        try {
4664            File tracesDir = tracesFile.getParentFile();
4665            if (!tracesDir.exists()) {
4666                tracesDir.mkdirs();
4667                if (!SELinux.restorecon(tracesDir)) {
4668                    return null;
4669                }
4670            }
4671            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4672
4673            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4674            tracesFile.createNewFile();
4675            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4676        } catch (IOException e) {
4677            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4678            return null;
4679        }
4680
4681        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4682        return tracesFile;
4683    }
4684
4685    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4686            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4687        // Use a FileObserver to detect when traces finish writing.
4688        // The order of traces is considered important to maintain for legibility.
4689        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4690            @Override
4691            public synchronized void onEvent(int event, String path) { notify(); }
4692        };
4693
4694        try {
4695            observer.startWatching();
4696
4697            // First collect all of the stacks of the most important pids.
4698            if (firstPids != null) {
4699                try {
4700                    int num = firstPids.size();
4701                    for (int i = 0; i < num; i++) {
4702                        synchronized (observer) {
4703                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4704                            observer.wait(200);  // Wait for write-close, give up after 200msec
4705                        }
4706                    }
4707                } catch (InterruptedException e) {
4708                    Slog.wtf(TAG, e);
4709                }
4710            }
4711
4712            // Next collect the stacks of the native pids
4713            if (nativeProcs != null) {
4714                int[] pids = Process.getPidsForCommands(nativeProcs);
4715                if (pids != null) {
4716                    for (int pid : pids) {
4717                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4718                    }
4719                }
4720            }
4721
4722            // Lastly, measure CPU usage.
4723            if (processCpuTracker != null) {
4724                processCpuTracker.init();
4725                System.gc();
4726                processCpuTracker.update();
4727                try {
4728                    synchronized (processCpuTracker) {
4729                        processCpuTracker.wait(500); // measure over 1/2 second.
4730                    }
4731                } catch (InterruptedException e) {
4732                }
4733                processCpuTracker.update();
4734
4735                // We'll take the stack crawls of just the top apps using CPU.
4736                final int N = processCpuTracker.countWorkingStats();
4737                int numProcs = 0;
4738                for (int i=0; i<N && numProcs<5; i++) {
4739                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4740                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4741                        numProcs++;
4742                        try {
4743                            synchronized (observer) {
4744                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4745                                observer.wait(200);  // Wait for write-close, give up after 200msec
4746                            }
4747                        } catch (InterruptedException e) {
4748                            Slog.wtf(TAG, e);
4749                        }
4750
4751                    }
4752                }
4753            }
4754        } finally {
4755            observer.stopWatching();
4756        }
4757    }
4758
4759    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4760        if (true || IS_USER_BUILD) {
4761            return;
4762        }
4763        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4764        if (tracesPath == null || tracesPath.length() == 0) {
4765            return;
4766        }
4767
4768        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4769        StrictMode.allowThreadDiskWrites();
4770        try {
4771            final File tracesFile = new File(tracesPath);
4772            final File tracesDir = tracesFile.getParentFile();
4773            final File tracesTmp = new File(tracesDir, "__tmp__");
4774            try {
4775                if (!tracesDir.exists()) {
4776                    tracesDir.mkdirs();
4777                    if (!SELinux.restorecon(tracesDir.getPath())) {
4778                        return;
4779                    }
4780                }
4781                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4782
4783                if (tracesFile.exists()) {
4784                    tracesTmp.delete();
4785                    tracesFile.renameTo(tracesTmp);
4786                }
4787                StringBuilder sb = new StringBuilder();
4788                Time tobj = new Time();
4789                tobj.set(System.currentTimeMillis());
4790                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4791                sb.append(": ");
4792                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4793                sb.append(" since ");
4794                sb.append(msg);
4795                FileOutputStream fos = new FileOutputStream(tracesFile);
4796                fos.write(sb.toString().getBytes());
4797                if (app == null) {
4798                    fos.write("\n*** No application process!".getBytes());
4799                }
4800                fos.close();
4801                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4802            } catch (IOException e) {
4803                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4804                return;
4805            }
4806
4807            if (app != null) {
4808                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4809                firstPids.add(app.pid);
4810                dumpStackTraces(tracesPath, firstPids, null, null, null);
4811            }
4812
4813            File lastTracesFile = null;
4814            File curTracesFile = null;
4815            for (int i=9; i>=0; i--) {
4816                String name = String.format(Locale.US, "slow%02d.txt", i);
4817                curTracesFile = new File(tracesDir, name);
4818                if (curTracesFile.exists()) {
4819                    if (lastTracesFile != null) {
4820                        curTracesFile.renameTo(lastTracesFile);
4821                    } else {
4822                        curTracesFile.delete();
4823                    }
4824                }
4825                lastTracesFile = curTracesFile;
4826            }
4827            tracesFile.renameTo(curTracesFile);
4828            if (tracesTmp.exists()) {
4829                tracesTmp.renameTo(tracesFile);
4830            }
4831        } finally {
4832            StrictMode.setThreadPolicy(oldPolicy);
4833        }
4834    }
4835
4836    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4837            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4838        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4839        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4840
4841        if (mController != null) {
4842            try {
4843                // 0 == continue, -1 = kill process immediately
4844                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4845                if (res < 0 && app.pid != MY_PID) {
4846                    app.kill("anr", true);
4847                }
4848            } catch (RemoteException e) {
4849                mController = null;
4850                Watchdog.getInstance().setActivityController(null);
4851            }
4852        }
4853
4854        long anrTime = SystemClock.uptimeMillis();
4855        if (MONITOR_CPU_USAGE) {
4856            updateCpuStatsNow();
4857        }
4858
4859        synchronized (this) {
4860            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4861            if (mShuttingDown) {
4862                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4863                return;
4864            } else if (app.notResponding) {
4865                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4866                return;
4867            } else if (app.crashing) {
4868                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4869                return;
4870            }
4871
4872            // In case we come through here for the same app before completing
4873            // this one, mark as anring now so we will bail out.
4874            app.notResponding = true;
4875
4876            // Log the ANR to the event log.
4877            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4878                    app.processName, app.info.flags, annotation);
4879
4880            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4881            firstPids.add(app.pid);
4882
4883            int parentPid = app.pid;
4884            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4885            if (parentPid != app.pid) firstPids.add(parentPid);
4886
4887            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4888
4889            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4890                ProcessRecord r = mLruProcesses.get(i);
4891                if (r != null && r.thread != null) {
4892                    int pid = r.pid;
4893                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4894                        if (r.persistent) {
4895                            firstPids.add(pid);
4896                        } else {
4897                            lastPids.put(pid, Boolean.TRUE);
4898                        }
4899                    }
4900                }
4901            }
4902        }
4903
4904        // Log the ANR to the main log.
4905        StringBuilder info = new StringBuilder();
4906        info.setLength(0);
4907        info.append("ANR in ").append(app.processName);
4908        if (activity != null && activity.shortComponentName != null) {
4909            info.append(" (").append(activity.shortComponentName).append(")");
4910        }
4911        info.append("\n");
4912        info.append("PID: ").append(app.pid).append("\n");
4913        if (annotation != null) {
4914            info.append("Reason: ").append(annotation).append("\n");
4915        }
4916        if (parent != null && parent != activity) {
4917            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4918        }
4919
4920        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4921
4922        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4923                NATIVE_STACKS_OF_INTEREST);
4924
4925        String cpuInfo = null;
4926        if (MONITOR_CPU_USAGE) {
4927            updateCpuStatsNow();
4928            synchronized (mProcessCpuTracker) {
4929                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4930            }
4931            info.append(processCpuTracker.printCurrentLoad());
4932            info.append(cpuInfo);
4933        }
4934
4935        info.append(processCpuTracker.printCurrentState(anrTime));
4936
4937        Slog.e(TAG, info.toString());
4938        if (tracesFile == null) {
4939            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4940            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4941        }
4942
4943        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4944                cpuInfo, tracesFile, null);
4945
4946        if (mController != null) {
4947            try {
4948                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4949                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4950                if (res != 0) {
4951                    if (res < 0 && app.pid != MY_PID) {
4952                        app.kill("anr", true);
4953                    } else {
4954                        synchronized (this) {
4955                            mServices.scheduleServiceTimeoutLocked(app);
4956                        }
4957                    }
4958                    return;
4959                }
4960            } catch (RemoteException e) {
4961                mController = null;
4962                Watchdog.getInstance().setActivityController(null);
4963            }
4964        }
4965
4966        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4967        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4968                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4969
4970        synchronized (this) {
4971            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4972                app.kill("bg anr", true);
4973                return;
4974            }
4975
4976            // Set the app's notResponding state, and look up the errorReportReceiver
4977            makeAppNotRespondingLocked(app,
4978                    activity != null ? activity.shortComponentName : null,
4979                    annotation != null ? "ANR " + annotation : "ANR",
4980                    info.toString());
4981
4982            // Bring up the infamous App Not Responding dialog
4983            Message msg = Message.obtain();
4984            HashMap<String, Object> map = new HashMap<String, Object>();
4985            msg.what = SHOW_NOT_RESPONDING_MSG;
4986            msg.obj = map;
4987            msg.arg1 = aboveSystem ? 1 : 0;
4988            map.put("app", app);
4989            if (activity != null) {
4990                map.put("activity", activity);
4991            }
4992
4993            mHandler.sendMessage(msg);
4994        }
4995    }
4996
4997    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4998        if (!mLaunchWarningShown) {
4999            mLaunchWarningShown = true;
5000            mHandler.post(new Runnable() {
5001                @Override
5002                public void run() {
5003                    synchronized (ActivityManagerService.this) {
5004                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5005                        d.show();
5006                        mHandler.postDelayed(new Runnable() {
5007                            @Override
5008                            public void run() {
5009                                synchronized (ActivityManagerService.this) {
5010                                    d.dismiss();
5011                                    mLaunchWarningShown = false;
5012                                }
5013                            }
5014                        }, 4000);
5015                    }
5016                }
5017            });
5018        }
5019    }
5020
5021    @Override
5022    public boolean clearApplicationUserData(final String packageName,
5023            final IPackageDataObserver observer, int userId) {
5024        enforceNotIsolatedCaller("clearApplicationUserData");
5025        int uid = Binder.getCallingUid();
5026        int pid = Binder.getCallingPid();
5027        userId = handleIncomingUser(pid, uid,
5028                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5029        long callingId = Binder.clearCallingIdentity();
5030        try {
5031            IPackageManager pm = AppGlobals.getPackageManager();
5032            int pkgUid = -1;
5033            synchronized(this) {
5034                try {
5035                    pkgUid = pm.getPackageUid(packageName, userId);
5036                } catch (RemoteException e) {
5037                }
5038                if (pkgUid == -1) {
5039                    Slog.w(TAG, "Invalid packageName: " + packageName);
5040                    if (observer != null) {
5041                        try {
5042                            observer.onRemoveCompleted(packageName, false);
5043                        } catch (RemoteException e) {
5044                            Slog.i(TAG, "Observer no longer exists.");
5045                        }
5046                    }
5047                    return false;
5048                }
5049                if (uid == pkgUid || checkComponentPermission(
5050                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5051                        pid, uid, -1, true)
5052                        == PackageManager.PERMISSION_GRANTED) {
5053                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5054                } else {
5055                    throw new SecurityException("PID " + pid + " does not have permission "
5056                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5057                                    + " of package " + packageName);
5058                }
5059
5060                // Remove all tasks match the cleared application package and user
5061                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5062                    final TaskRecord tr = mRecentTasks.get(i);
5063                    final String taskPackageName =
5064                            tr.getBaseIntent().getComponent().getPackageName();
5065                    if (tr.userId != userId) continue;
5066                    if (!taskPackageName.equals(packageName)) continue;
5067                    removeTaskByIdLocked(tr.taskId, false);
5068                }
5069            }
5070
5071            try {
5072                // Clear application user data
5073                pm.clearApplicationUserData(packageName, observer, userId);
5074
5075                synchronized(this) {
5076                    // Remove all permissions granted from/to this package
5077                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5078                }
5079
5080                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5081                        Uri.fromParts("package", packageName, null));
5082                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5083                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5084                        null, null, 0, null, null, null, false, false, userId);
5085            } catch (RemoteException e) {
5086            }
5087        } finally {
5088            Binder.restoreCallingIdentity(callingId);
5089        }
5090        return true;
5091    }
5092
5093    @Override
5094    public void killBackgroundProcesses(final String packageName, int userId) {
5095        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5096                != PackageManager.PERMISSION_GRANTED &&
5097                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5098                        != PackageManager.PERMISSION_GRANTED) {
5099            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5100                    + Binder.getCallingPid()
5101                    + ", uid=" + Binder.getCallingUid()
5102                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5103            Slog.w(TAG, msg);
5104            throw new SecurityException(msg);
5105        }
5106
5107        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5108                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5109        long callingId = Binder.clearCallingIdentity();
5110        try {
5111            IPackageManager pm = AppGlobals.getPackageManager();
5112            synchronized(this) {
5113                int appId = -1;
5114                try {
5115                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5116                } catch (RemoteException e) {
5117                }
5118                if (appId == -1) {
5119                    Slog.w(TAG, "Invalid packageName: " + packageName);
5120                    return;
5121                }
5122                killPackageProcessesLocked(packageName, appId, userId,
5123                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5124            }
5125        } finally {
5126            Binder.restoreCallingIdentity(callingId);
5127        }
5128    }
5129
5130    @Override
5131    public void killAllBackgroundProcesses() {
5132        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5133                != PackageManager.PERMISSION_GRANTED) {
5134            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5135                    + Binder.getCallingPid()
5136                    + ", uid=" + Binder.getCallingUid()
5137                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5138            Slog.w(TAG, msg);
5139            throw new SecurityException(msg);
5140        }
5141
5142        long callingId = Binder.clearCallingIdentity();
5143        try {
5144            synchronized(this) {
5145                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5146                final int NP = mProcessNames.getMap().size();
5147                for (int ip=0; ip<NP; ip++) {
5148                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5149                    final int NA = apps.size();
5150                    for (int ia=0; ia<NA; ia++) {
5151                        ProcessRecord app = apps.valueAt(ia);
5152                        if (app.persistent) {
5153                            // we don't kill persistent processes
5154                            continue;
5155                        }
5156                        if (app.removed) {
5157                            procs.add(app);
5158                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5159                            app.removed = true;
5160                            procs.add(app);
5161                        }
5162                    }
5163                }
5164
5165                int N = procs.size();
5166                for (int i=0; i<N; i++) {
5167                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5168                }
5169                mAllowLowerMemLevel = true;
5170                updateOomAdjLocked();
5171                doLowMemReportIfNeededLocked(null);
5172            }
5173        } finally {
5174            Binder.restoreCallingIdentity(callingId);
5175        }
5176    }
5177
5178    @Override
5179    public void forceStopPackage(final String packageName, int userId) {
5180        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5181                != PackageManager.PERMISSION_GRANTED) {
5182            String msg = "Permission Denial: forceStopPackage() from pid="
5183                    + Binder.getCallingPid()
5184                    + ", uid=" + Binder.getCallingUid()
5185                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5186            Slog.w(TAG, msg);
5187            throw new SecurityException(msg);
5188        }
5189        final int callingPid = Binder.getCallingPid();
5190        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5191                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5192        long callingId = Binder.clearCallingIdentity();
5193        try {
5194            IPackageManager pm = AppGlobals.getPackageManager();
5195            synchronized(this) {
5196                int[] users = userId == UserHandle.USER_ALL
5197                        ? getUsersLocked() : new int[] { userId };
5198                for (int user : users) {
5199                    int pkgUid = -1;
5200                    try {
5201                        pkgUid = pm.getPackageUid(packageName, user);
5202                    } catch (RemoteException e) {
5203                    }
5204                    if (pkgUid == -1) {
5205                        Slog.w(TAG, "Invalid packageName: " + packageName);
5206                        continue;
5207                    }
5208                    try {
5209                        pm.setPackageStoppedState(packageName, true, user);
5210                    } catch (RemoteException e) {
5211                    } catch (IllegalArgumentException e) {
5212                        Slog.w(TAG, "Failed trying to unstop package "
5213                                + packageName + ": " + e);
5214                    }
5215                    if (isUserRunningLocked(user, false)) {
5216                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5217                    }
5218                }
5219            }
5220        } finally {
5221            Binder.restoreCallingIdentity(callingId);
5222        }
5223    }
5224
5225    @Override
5226    public void addPackageDependency(String packageName) {
5227        synchronized (this) {
5228            int callingPid = Binder.getCallingPid();
5229            if (callingPid == Process.myPid()) {
5230                //  Yeah, um, no.
5231                Slog.w(TAG, "Can't addPackageDependency on system process");
5232                return;
5233            }
5234            ProcessRecord proc;
5235            synchronized (mPidsSelfLocked) {
5236                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5237            }
5238            if (proc != null) {
5239                if (proc.pkgDeps == null) {
5240                    proc.pkgDeps = new ArraySet<String>(1);
5241                }
5242                proc.pkgDeps.add(packageName);
5243            }
5244        }
5245    }
5246
5247    /*
5248     * The pkg name and app id have to be specified.
5249     */
5250    @Override
5251    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5252        if (pkg == null) {
5253            return;
5254        }
5255        // Make sure the uid is valid.
5256        if (appid < 0) {
5257            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5258            return;
5259        }
5260        int callerUid = Binder.getCallingUid();
5261        // Only the system server can kill an application
5262        if (callerUid == Process.SYSTEM_UID) {
5263            // Post an aysnc message to kill the application
5264            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5265            msg.arg1 = appid;
5266            msg.arg2 = 0;
5267            Bundle bundle = new Bundle();
5268            bundle.putString("pkg", pkg);
5269            bundle.putString("reason", reason);
5270            msg.obj = bundle;
5271            mHandler.sendMessage(msg);
5272        } else {
5273            throw new SecurityException(callerUid + " cannot kill pkg: " +
5274                    pkg);
5275        }
5276    }
5277
5278    @Override
5279    public void closeSystemDialogs(String reason) {
5280        enforceNotIsolatedCaller("closeSystemDialogs");
5281
5282        final int pid = Binder.getCallingPid();
5283        final int uid = Binder.getCallingUid();
5284        final long origId = Binder.clearCallingIdentity();
5285        try {
5286            synchronized (this) {
5287                // Only allow this from foreground processes, so that background
5288                // applications can't abuse it to prevent system UI from being shown.
5289                if (uid >= Process.FIRST_APPLICATION_UID) {
5290                    ProcessRecord proc;
5291                    synchronized (mPidsSelfLocked) {
5292                        proc = mPidsSelfLocked.get(pid);
5293                    }
5294                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5295                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5296                                + " from background process " + proc);
5297                        return;
5298                    }
5299                }
5300                closeSystemDialogsLocked(reason);
5301            }
5302        } finally {
5303            Binder.restoreCallingIdentity(origId);
5304        }
5305    }
5306
5307    void closeSystemDialogsLocked(String reason) {
5308        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5309        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5310                | Intent.FLAG_RECEIVER_FOREGROUND);
5311        if (reason != null) {
5312            intent.putExtra("reason", reason);
5313        }
5314        mWindowManager.closeSystemDialogs(reason);
5315
5316        mStackSupervisor.closeSystemDialogsLocked();
5317
5318        broadcastIntentLocked(null, null, intent, null,
5319                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5320                Process.SYSTEM_UID, UserHandle.USER_ALL);
5321    }
5322
5323    @Override
5324    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5325        enforceNotIsolatedCaller("getProcessMemoryInfo");
5326        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5327        for (int i=pids.length-1; i>=0; i--) {
5328            ProcessRecord proc;
5329            int oomAdj;
5330            synchronized (this) {
5331                synchronized (mPidsSelfLocked) {
5332                    proc = mPidsSelfLocked.get(pids[i]);
5333                    oomAdj = proc != null ? proc.setAdj : 0;
5334                }
5335            }
5336            infos[i] = new Debug.MemoryInfo();
5337            Debug.getMemoryInfo(pids[i], infos[i]);
5338            if (proc != null) {
5339                synchronized (this) {
5340                    if (proc.thread != null && proc.setAdj == oomAdj) {
5341                        // Record this for posterity if the process has been stable.
5342                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5343                                infos[i].getTotalUss(), false, proc.pkgList);
5344                    }
5345                }
5346            }
5347        }
5348        return infos;
5349    }
5350
5351    @Override
5352    public long[] getProcessPss(int[] pids) {
5353        enforceNotIsolatedCaller("getProcessPss");
5354        long[] pss = new long[pids.length];
5355        for (int i=pids.length-1; i>=0; i--) {
5356            ProcessRecord proc;
5357            int oomAdj;
5358            synchronized (this) {
5359                synchronized (mPidsSelfLocked) {
5360                    proc = mPidsSelfLocked.get(pids[i]);
5361                    oomAdj = proc != null ? proc.setAdj : 0;
5362                }
5363            }
5364            long[] tmpUss = new long[1];
5365            pss[i] = Debug.getPss(pids[i], tmpUss);
5366            if (proc != null) {
5367                synchronized (this) {
5368                    if (proc.thread != null && proc.setAdj == oomAdj) {
5369                        // Record this for posterity if the process has been stable.
5370                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5371                    }
5372                }
5373            }
5374        }
5375        return pss;
5376    }
5377
5378    @Override
5379    public void killApplicationProcess(String processName, int uid) {
5380        if (processName == null) {
5381            return;
5382        }
5383
5384        int callerUid = Binder.getCallingUid();
5385        // Only the system server can kill an application
5386        if (callerUid == Process.SYSTEM_UID) {
5387            synchronized (this) {
5388                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5389                if (app != null && app.thread != null) {
5390                    try {
5391                        app.thread.scheduleSuicide();
5392                    } catch (RemoteException e) {
5393                        // If the other end already died, then our work here is done.
5394                    }
5395                } else {
5396                    Slog.w(TAG, "Process/uid not found attempting kill of "
5397                            + processName + " / " + uid);
5398                }
5399            }
5400        } else {
5401            throw new SecurityException(callerUid + " cannot kill app process: " +
5402                    processName);
5403        }
5404    }
5405
5406    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5407        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5408                false, true, false, false, UserHandle.getUserId(uid), reason);
5409        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5410                Uri.fromParts("package", packageName, null));
5411        if (!mProcessesReady) {
5412            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5413                    | Intent.FLAG_RECEIVER_FOREGROUND);
5414        }
5415        intent.putExtra(Intent.EXTRA_UID, uid);
5416        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5417        broadcastIntentLocked(null, null, intent,
5418                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5419                false, false,
5420                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5421    }
5422
5423    private void forceStopUserLocked(int userId, String reason) {
5424        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5425        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5426        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5427                | Intent.FLAG_RECEIVER_FOREGROUND);
5428        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5429        broadcastIntentLocked(null, null, intent,
5430                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5431                false, false,
5432                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5433    }
5434
5435    private final boolean killPackageProcessesLocked(String packageName, int appId,
5436            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5437            boolean doit, boolean evenPersistent, String reason) {
5438        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5439
5440        // Remove all processes this package may have touched: all with the
5441        // same UID (except for the system or root user), and all whose name
5442        // matches the package name.
5443        final int NP = mProcessNames.getMap().size();
5444        for (int ip=0; ip<NP; ip++) {
5445            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5446            final int NA = apps.size();
5447            for (int ia=0; ia<NA; ia++) {
5448                ProcessRecord app = apps.valueAt(ia);
5449                if (app.persistent && !evenPersistent) {
5450                    // we don't kill persistent processes
5451                    continue;
5452                }
5453                if (app.removed) {
5454                    if (doit) {
5455                        procs.add(app);
5456                    }
5457                    continue;
5458                }
5459
5460                // Skip process if it doesn't meet our oom adj requirement.
5461                if (app.setAdj < minOomAdj) {
5462                    continue;
5463                }
5464
5465                // If no package is specified, we call all processes under the
5466                // give user id.
5467                if (packageName == null) {
5468                    if (app.userId != userId) {
5469                        continue;
5470                    }
5471                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5472                        continue;
5473                    }
5474                // Package has been specified, we want to hit all processes
5475                // that match it.  We need to qualify this by the processes
5476                // that are running under the specified app and user ID.
5477                } else {
5478                    final boolean isDep = app.pkgDeps != null
5479                            && app.pkgDeps.contains(packageName);
5480                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5481                        continue;
5482                    }
5483                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5484                        continue;
5485                    }
5486                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5487                        continue;
5488                    }
5489                }
5490
5491                // Process has passed all conditions, kill it!
5492                if (!doit) {
5493                    return true;
5494                }
5495                app.removed = true;
5496                procs.add(app);
5497            }
5498        }
5499
5500        int N = procs.size();
5501        for (int i=0; i<N; i++) {
5502            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5503        }
5504        updateOomAdjLocked();
5505        return N > 0;
5506    }
5507
5508    private final boolean forceStopPackageLocked(String name, int appId,
5509            boolean callerWillRestart, boolean purgeCache, boolean doit,
5510            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5511        int i;
5512        int N;
5513
5514        if (userId == UserHandle.USER_ALL && name == null) {
5515            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5516        }
5517
5518        if (appId < 0 && name != null) {
5519            try {
5520                appId = UserHandle.getAppId(
5521                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5522            } catch (RemoteException e) {
5523            }
5524        }
5525
5526        if (doit) {
5527            if (name != null) {
5528                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5529                        + " user=" + userId + ": " + reason);
5530            } else {
5531                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5532            }
5533
5534            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5535            for (int ip=pmap.size()-1; ip>=0; ip--) {
5536                SparseArray<Long> ba = pmap.valueAt(ip);
5537                for (i=ba.size()-1; i>=0; i--) {
5538                    boolean remove = false;
5539                    final int entUid = ba.keyAt(i);
5540                    if (name != null) {
5541                        if (userId == UserHandle.USER_ALL) {
5542                            if (UserHandle.getAppId(entUid) == appId) {
5543                                remove = true;
5544                            }
5545                        } else {
5546                            if (entUid == UserHandle.getUid(userId, appId)) {
5547                                remove = true;
5548                            }
5549                        }
5550                    } else if (UserHandle.getUserId(entUid) == userId) {
5551                        remove = true;
5552                    }
5553                    if (remove) {
5554                        ba.removeAt(i);
5555                    }
5556                }
5557                if (ba.size() == 0) {
5558                    pmap.removeAt(ip);
5559                }
5560            }
5561        }
5562
5563        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5564                -100, callerWillRestart, true, doit, evenPersistent,
5565                name == null ? ("stop user " + userId) : ("stop " + name));
5566
5567        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5568            if (!doit) {
5569                return true;
5570            }
5571            didSomething = true;
5572        }
5573
5574        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5575            if (!doit) {
5576                return true;
5577            }
5578            didSomething = true;
5579        }
5580
5581        if (name == null) {
5582            // Remove all sticky broadcasts from this user.
5583            mStickyBroadcasts.remove(userId);
5584        }
5585
5586        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5587        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5588                userId, providers)) {
5589            if (!doit) {
5590                return true;
5591            }
5592            didSomething = true;
5593        }
5594        N = providers.size();
5595        for (i=0; i<N; i++) {
5596            removeDyingProviderLocked(null, providers.get(i), true);
5597        }
5598
5599        // Remove transient permissions granted from/to this package/user
5600        removeUriPermissionsForPackageLocked(name, userId, false);
5601
5602        if (name == null || uninstalling) {
5603            // Remove pending intents.  For now we only do this when force
5604            // stopping users, because we have some problems when doing this
5605            // for packages -- app widgets are not currently cleaned up for
5606            // such packages, so they can be left with bad pending intents.
5607            if (mIntentSenderRecords.size() > 0) {
5608                Iterator<WeakReference<PendingIntentRecord>> it
5609                        = mIntentSenderRecords.values().iterator();
5610                while (it.hasNext()) {
5611                    WeakReference<PendingIntentRecord> wpir = it.next();
5612                    if (wpir == null) {
5613                        it.remove();
5614                        continue;
5615                    }
5616                    PendingIntentRecord pir = wpir.get();
5617                    if (pir == null) {
5618                        it.remove();
5619                        continue;
5620                    }
5621                    if (name == null) {
5622                        // Stopping user, remove all objects for the user.
5623                        if (pir.key.userId != userId) {
5624                            // Not the same user, skip it.
5625                            continue;
5626                        }
5627                    } else {
5628                        if (UserHandle.getAppId(pir.uid) != appId) {
5629                            // Different app id, skip it.
5630                            continue;
5631                        }
5632                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5633                            // Different user, skip it.
5634                            continue;
5635                        }
5636                        if (!pir.key.packageName.equals(name)) {
5637                            // Different package, skip it.
5638                            continue;
5639                        }
5640                    }
5641                    if (!doit) {
5642                        return true;
5643                    }
5644                    didSomething = true;
5645                    it.remove();
5646                    pir.canceled = true;
5647                    if (pir.key.activity != null) {
5648                        pir.key.activity.pendingResults.remove(pir.ref);
5649                    }
5650                }
5651            }
5652        }
5653
5654        if (doit) {
5655            if (purgeCache && name != null) {
5656                AttributeCache ac = AttributeCache.instance();
5657                if (ac != null) {
5658                    ac.removePackage(name);
5659                }
5660            }
5661            if (mBooted) {
5662                mStackSupervisor.resumeTopActivitiesLocked();
5663                mStackSupervisor.scheduleIdleLocked();
5664            }
5665        }
5666
5667        return didSomething;
5668    }
5669
5670    private final boolean removeProcessLocked(ProcessRecord app,
5671            boolean callerWillRestart, boolean allowRestart, String reason) {
5672        final String name = app.processName;
5673        final int uid = app.uid;
5674        if (DEBUG_PROCESSES) Slog.d(
5675            TAG, "Force removing proc " + app.toShortString() + " (" + name
5676            + "/" + uid + ")");
5677
5678        mProcessNames.remove(name, uid);
5679        mIsolatedProcesses.remove(app.uid);
5680        if (mHeavyWeightProcess == app) {
5681            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5682                    mHeavyWeightProcess.userId, 0));
5683            mHeavyWeightProcess = null;
5684        }
5685        boolean needRestart = false;
5686        if (app.pid > 0 && app.pid != MY_PID) {
5687            int pid = app.pid;
5688            synchronized (mPidsSelfLocked) {
5689                mPidsSelfLocked.remove(pid);
5690                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5691            }
5692            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5693            if (app.isolated) {
5694                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5695            }
5696            app.kill(reason, true);
5697            handleAppDiedLocked(app, true, allowRestart);
5698            removeLruProcessLocked(app);
5699
5700            if (app.persistent && !app.isolated) {
5701                if (!callerWillRestart) {
5702                    addAppLocked(app.info, false, null /* ABI override */);
5703                } else {
5704                    needRestart = true;
5705                }
5706            }
5707        } else {
5708            mRemovedProcesses.add(app);
5709        }
5710
5711        return needRestart;
5712    }
5713
5714    private final void processStartTimedOutLocked(ProcessRecord app) {
5715        final int pid = app.pid;
5716        boolean gone = false;
5717        synchronized (mPidsSelfLocked) {
5718            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5719            if (knownApp != null && knownApp.thread == null) {
5720                mPidsSelfLocked.remove(pid);
5721                gone = true;
5722            }
5723        }
5724
5725        if (gone) {
5726            Slog.w(TAG, "Process " + app + " failed to attach");
5727            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5728                    pid, app.uid, app.processName);
5729            mProcessNames.remove(app.processName, app.uid);
5730            mIsolatedProcesses.remove(app.uid);
5731            if (mHeavyWeightProcess == app) {
5732                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5733                        mHeavyWeightProcess.userId, 0));
5734                mHeavyWeightProcess = null;
5735            }
5736            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5737            if (app.isolated) {
5738                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5739            }
5740            // Take care of any launching providers waiting for this process.
5741            checkAppInLaunchingProvidersLocked(app, true);
5742            // Take care of any services that are waiting for the process.
5743            mServices.processStartTimedOutLocked(app);
5744            app.kill("start timeout", true);
5745            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5746                Slog.w(TAG, "Unattached app died before backup, skipping");
5747                try {
5748                    IBackupManager bm = IBackupManager.Stub.asInterface(
5749                            ServiceManager.getService(Context.BACKUP_SERVICE));
5750                    bm.agentDisconnected(app.info.packageName);
5751                } catch (RemoteException e) {
5752                    // Can't happen; the backup manager is local
5753                }
5754            }
5755            if (isPendingBroadcastProcessLocked(pid)) {
5756                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5757                skipPendingBroadcastLocked(pid);
5758            }
5759        } else {
5760            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5761        }
5762    }
5763
5764    private final boolean attachApplicationLocked(IApplicationThread thread,
5765            int pid) {
5766
5767        // Find the application record that is being attached...  either via
5768        // the pid if we are running in multiple processes, or just pull the
5769        // next app record if we are emulating process with anonymous threads.
5770        ProcessRecord app;
5771        if (pid != MY_PID && pid >= 0) {
5772            synchronized (mPidsSelfLocked) {
5773                app = mPidsSelfLocked.get(pid);
5774            }
5775        } else {
5776            app = null;
5777        }
5778
5779        if (app == null) {
5780            Slog.w(TAG, "No pending application record for pid " + pid
5781                    + " (IApplicationThread " + thread + "); dropping process");
5782            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5783            if (pid > 0 && pid != MY_PID) {
5784                Process.killProcessQuiet(pid);
5785                //TODO: Process.killProcessGroup(app.info.uid, pid);
5786            } else {
5787                try {
5788                    thread.scheduleExit();
5789                } catch (Exception e) {
5790                    // Ignore exceptions.
5791                }
5792            }
5793            return false;
5794        }
5795
5796        // If this application record is still attached to a previous
5797        // process, clean it up now.
5798        if (app.thread != null) {
5799            handleAppDiedLocked(app, true, true);
5800        }
5801
5802        // Tell the process all about itself.
5803
5804        if (localLOGV) Slog.v(
5805                TAG, "Binding process pid " + pid + " to record " + app);
5806
5807        final String processName = app.processName;
5808        try {
5809            AppDeathRecipient adr = new AppDeathRecipient(
5810                    app, pid, thread);
5811            thread.asBinder().linkToDeath(adr, 0);
5812            app.deathRecipient = adr;
5813        } catch (RemoteException e) {
5814            app.resetPackageList(mProcessStats);
5815            startProcessLocked(app, "link fail", processName);
5816            return false;
5817        }
5818
5819        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5820
5821        app.makeActive(thread, mProcessStats);
5822        app.curAdj = app.setAdj = -100;
5823        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5824        app.forcingToForeground = null;
5825        updateProcessForegroundLocked(app, false, false);
5826        app.hasShownUi = false;
5827        app.debugging = false;
5828        app.cached = false;
5829
5830        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5831
5832        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5833        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5834
5835        if (!normalMode) {
5836            Slog.i(TAG, "Launching preboot mode app: " + app);
5837        }
5838
5839        if (localLOGV) Slog.v(
5840            TAG, "New app record " + app
5841            + " thread=" + thread.asBinder() + " pid=" + pid);
5842        try {
5843            int testMode = IApplicationThread.DEBUG_OFF;
5844            if (mDebugApp != null && mDebugApp.equals(processName)) {
5845                testMode = mWaitForDebugger
5846                    ? IApplicationThread.DEBUG_WAIT
5847                    : IApplicationThread.DEBUG_ON;
5848                app.debugging = true;
5849                if (mDebugTransient) {
5850                    mDebugApp = mOrigDebugApp;
5851                    mWaitForDebugger = mOrigWaitForDebugger;
5852                }
5853            }
5854            String profileFile = app.instrumentationProfileFile;
5855            ParcelFileDescriptor profileFd = null;
5856            int samplingInterval = 0;
5857            boolean profileAutoStop = false;
5858            if (mProfileApp != null && mProfileApp.equals(processName)) {
5859                mProfileProc = app;
5860                profileFile = mProfileFile;
5861                profileFd = mProfileFd;
5862                samplingInterval = mSamplingInterval;
5863                profileAutoStop = mAutoStopProfiler;
5864            }
5865            boolean enableOpenGlTrace = false;
5866            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5867                enableOpenGlTrace = true;
5868                mOpenGlTraceApp = null;
5869            }
5870
5871            // If the app is being launched for restore or full backup, set it up specially
5872            boolean isRestrictedBackupMode = false;
5873            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5874                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5875                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5876                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5877            }
5878
5879            ensurePackageDexOpt(app.instrumentationInfo != null
5880                    ? app.instrumentationInfo.packageName
5881                    : app.info.packageName);
5882            if (app.instrumentationClass != null) {
5883                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5884            }
5885            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5886                    + processName + " with config " + mConfiguration);
5887            ApplicationInfo appInfo = app.instrumentationInfo != null
5888                    ? app.instrumentationInfo : app.info;
5889            app.compat = compatibilityInfoForPackageLocked(appInfo);
5890            if (profileFd != null) {
5891                profileFd = profileFd.dup();
5892            }
5893            ProfilerInfo profilerInfo = profileFile == null ? null
5894                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5895            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5896                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5897                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5898                    isRestrictedBackupMode || !normalMode, app.persistent,
5899                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5900                    mCoreSettingsObserver.getCoreSettingsLocked());
5901            updateLruProcessLocked(app, false, null);
5902            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5903        } catch (Exception e) {
5904            // todo: Yikes!  What should we do?  For now we will try to
5905            // start another process, but that could easily get us in
5906            // an infinite loop of restarting processes...
5907            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5908
5909            app.resetPackageList(mProcessStats);
5910            app.unlinkDeathRecipient();
5911            startProcessLocked(app, "bind fail", processName);
5912            return false;
5913        }
5914
5915        // Remove this record from the list of starting applications.
5916        mPersistentStartingProcesses.remove(app);
5917        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5918                "Attach application locked removing on hold: " + app);
5919        mProcessesOnHold.remove(app);
5920
5921        boolean badApp = false;
5922        boolean didSomething = false;
5923
5924        // See if the top visible activity is waiting to run in this process...
5925        if (normalMode) {
5926            try {
5927                if (mStackSupervisor.attachApplicationLocked(app)) {
5928                    didSomething = true;
5929                }
5930            } catch (Exception e) {
5931                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5932                badApp = true;
5933            }
5934        }
5935
5936        // Find any services that should be running in this process...
5937        if (!badApp) {
5938            try {
5939                didSomething |= mServices.attachApplicationLocked(app, processName);
5940            } catch (Exception e) {
5941                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5942                badApp = true;
5943            }
5944        }
5945
5946        // Check if a next-broadcast receiver is in this process...
5947        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5948            try {
5949                didSomething |= sendPendingBroadcastsLocked(app);
5950            } catch (Exception e) {
5951                // If the app died trying to launch the receiver we declare it 'bad'
5952                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
5953                badApp = true;
5954            }
5955        }
5956
5957        // Check whether the next backup agent is in this process...
5958        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5959            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5960            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5961            try {
5962                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5963                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5964                        mBackupTarget.backupMode);
5965            } catch (Exception e) {
5966                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
5967                badApp = true;
5968            }
5969        }
5970
5971        if (badApp) {
5972            app.kill("error during init", true);
5973            handleAppDiedLocked(app, false, true);
5974            return false;
5975        }
5976
5977        if (!didSomething) {
5978            updateOomAdjLocked();
5979        }
5980
5981        return true;
5982    }
5983
5984    @Override
5985    public final void attachApplication(IApplicationThread thread) {
5986        synchronized (this) {
5987            int callingPid = Binder.getCallingPid();
5988            final long origId = Binder.clearCallingIdentity();
5989            attachApplicationLocked(thread, callingPid);
5990            Binder.restoreCallingIdentity(origId);
5991        }
5992    }
5993
5994    @Override
5995    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5996        final long origId = Binder.clearCallingIdentity();
5997        synchronized (this) {
5998            ActivityStack stack = ActivityRecord.getStackLocked(token);
5999            if (stack != null) {
6000                ActivityRecord r =
6001                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6002                if (stopProfiling) {
6003                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6004                        try {
6005                            mProfileFd.close();
6006                        } catch (IOException e) {
6007                        }
6008                        clearProfilerLocked();
6009                    }
6010                }
6011            }
6012        }
6013        Binder.restoreCallingIdentity(origId);
6014    }
6015
6016    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6017        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6018                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6019    }
6020
6021    void enableScreenAfterBoot() {
6022        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6023                SystemClock.uptimeMillis());
6024        mWindowManager.enableScreenAfterBoot();
6025
6026        synchronized (this) {
6027            updateEventDispatchingLocked();
6028        }
6029    }
6030
6031    @Override
6032    public void showBootMessage(final CharSequence msg, final boolean always) {
6033        enforceNotIsolatedCaller("showBootMessage");
6034        mWindowManager.showBootMessage(msg, always);
6035    }
6036
6037    @Override
6038    public void keyguardWaitingForActivityDrawn() {
6039        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6040        final long token = Binder.clearCallingIdentity();
6041        try {
6042            synchronized (this) {
6043                if (DEBUG_LOCKSCREEN) logLockScreen("");
6044                mWindowManager.keyguardWaitingForActivityDrawn();
6045                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6046                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6047                }
6048            }
6049        } finally {
6050            Binder.restoreCallingIdentity(token);
6051        }
6052    }
6053
6054    final void finishBooting() {
6055        synchronized (this) {
6056            if (!mBootAnimationComplete) {
6057                mCallFinishBooting = true;
6058                return;
6059            }
6060            mCallFinishBooting = false;
6061        }
6062
6063        ArraySet<String> completedIsas = new ArraySet<String>();
6064        for (String abi : Build.SUPPORTED_ABIS) {
6065            Process.establishZygoteConnectionForAbi(abi);
6066            final String instructionSet = VMRuntime.getInstructionSet(abi);
6067            if (!completedIsas.contains(instructionSet)) {
6068                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6069                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6070                }
6071                completedIsas.add(instructionSet);
6072            }
6073        }
6074
6075        IntentFilter pkgFilter = new IntentFilter();
6076        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6077        pkgFilter.addDataScheme("package");
6078        mContext.registerReceiver(new BroadcastReceiver() {
6079            @Override
6080            public void onReceive(Context context, Intent intent) {
6081                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6082                if (pkgs != null) {
6083                    for (String pkg : pkgs) {
6084                        synchronized (ActivityManagerService.this) {
6085                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6086                                    0, "finished booting")) {
6087                                setResultCode(Activity.RESULT_OK);
6088                                return;
6089                            }
6090                        }
6091                    }
6092                }
6093            }
6094        }, pkgFilter);
6095
6096        // Let system services know.
6097        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6098
6099        synchronized (this) {
6100            // Ensure that any processes we had put on hold are now started
6101            // up.
6102            final int NP = mProcessesOnHold.size();
6103            if (NP > 0) {
6104                ArrayList<ProcessRecord> procs =
6105                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6106                for (int ip=0; ip<NP; ip++) {
6107                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6108                            + procs.get(ip));
6109                    startProcessLocked(procs.get(ip), "on-hold", null);
6110                }
6111            }
6112
6113            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6114                // Start looking for apps that are abusing wake locks.
6115                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6116                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6117                // Tell anyone interested that we are done booting!
6118                SystemProperties.set("sys.boot_completed", "1");
6119
6120                // And trigger dev.bootcomplete if we are not showing encryption progress
6121                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6122                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6123                    SystemProperties.set("dev.bootcomplete", "1");
6124                }
6125                for (int i=0; i<mStartedUsers.size(); i++) {
6126                    UserStartedState uss = mStartedUsers.valueAt(i);
6127                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6128                        uss.mState = UserStartedState.STATE_RUNNING;
6129                        final int userId = mStartedUsers.keyAt(i);
6130                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6131                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6132                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6133                        broadcastIntentLocked(null, null, intent, null,
6134                                new IIntentReceiver.Stub() {
6135                                    @Override
6136                                    public void performReceive(Intent intent, int resultCode,
6137                                            String data, Bundle extras, boolean ordered,
6138                                            boolean sticky, int sendingUser) {
6139                                        synchronized (ActivityManagerService.this) {
6140                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6141                                                    true, false);
6142                                        }
6143                                    }
6144                                },
6145                                0, null, null,
6146                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6147                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6148                                userId);
6149                    }
6150                }
6151                scheduleStartProfilesLocked();
6152            }
6153        }
6154    }
6155
6156    @Override
6157    public void bootAnimationComplete() {
6158        final boolean callFinishBooting;
6159        synchronized (this) {
6160            callFinishBooting = mCallFinishBooting;
6161            mBootAnimationComplete = true;
6162        }
6163        if (callFinishBooting) {
6164            finishBooting();
6165        }
6166    }
6167
6168    final void ensureBootCompleted() {
6169        boolean booting;
6170        boolean enableScreen;
6171        synchronized (this) {
6172            booting = mBooting;
6173            mBooting = false;
6174            enableScreen = !mBooted;
6175            mBooted = true;
6176        }
6177
6178        if (booting) {
6179            finishBooting();
6180        }
6181
6182        if (enableScreen) {
6183            enableScreenAfterBoot();
6184        }
6185    }
6186
6187    @Override
6188    public final void activityResumed(IBinder token) {
6189        final long origId = Binder.clearCallingIdentity();
6190        synchronized(this) {
6191            ActivityStack stack = ActivityRecord.getStackLocked(token);
6192            if (stack != null) {
6193                ActivityRecord.activityResumedLocked(token);
6194            }
6195        }
6196        Binder.restoreCallingIdentity(origId);
6197    }
6198
6199    @Override
6200    public final void activityPaused(IBinder token) {
6201        final long origId = Binder.clearCallingIdentity();
6202        synchronized(this) {
6203            ActivityStack stack = ActivityRecord.getStackLocked(token);
6204            if (stack != null) {
6205                stack.activityPausedLocked(token, false);
6206            }
6207        }
6208        Binder.restoreCallingIdentity(origId);
6209    }
6210
6211    @Override
6212    public final void activityStopped(IBinder token, Bundle icicle,
6213            PersistableBundle persistentState, CharSequence description) {
6214        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6215
6216        // Refuse possible leaked file descriptors
6217        if (icicle != null && icicle.hasFileDescriptors()) {
6218            throw new IllegalArgumentException("File descriptors passed in Bundle");
6219        }
6220
6221        final long origId = Binder.clearCallingIdentity();
6222
6223        synchronized (this) {
6224            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6225            if (r != null) {
6226                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6227            }
6228        }
6229
6230        trimApplications();
6231
6232        Binder.restoreCallingIdentity(origId);
6233    }
6234
6235    @Override
6236    public final void activityDestroyed(IBinder token) {
6237        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6238        synchronized (this) {
6239            ActivityStack stack = ActivityRecord.getStackLocked(token);
6240            if (stack != null) {
6241                stack.activityDestroyedLocked(token);
6242            }
6243        }
6244    }
6245
6246    @Override
6247    public final void backgroundResourcesReleased(IBinder token) {
6248        final long origId = Binder.clearCallingIdentity();
6249        try {
6250            synchronized (this) {
6251                ActivityStack stack = ActivityRecord.getStackLocked(token);
6252                if (stack != null) {
6253                    stack.backgroundResourcesReleased(token);
6254                }
6255            }
6256        } finally {
6257            Binder.restoreCallingIdentity(origId);
6258        }
6259    }
6260
6261    @Override
6262    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6263        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6264    }
6265
6266    @Override
6267    public final void notifyEnterAnimationComplete(IBinder token) {
6268        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6269    }
6270
6271    @Override
6272    public String getCallingPackage(IBinder token) {
6273        synchronized (this) {
6274            ActivityRecord r = getCallingRecordLocked(token);
6275            return r != null ? r.info.packageName : null;
6276        }
6277    }
6278
6279    @Override
6280    public ComponentName getCallingActivity(IBinder token) {
6281        synchronized (this) {
6282            ActivityRecord r = getCallingRecordLocked(token);
6283            return r != null ? r.intent.getComponent() : null;
6284        }
6285    }
6286
6287    private ActivityRecord getCallingRecordLocked(IBinder token) {
6288        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6289        if (r == null) {
6290            return null;
6291        }
6292        return r.resultTo;
6293    }
6294
6295    @Override
6296    public ComponentName getActivityClassForToken(IBinder token) {
6297        synchronized(this) {
6298            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6299            if (r == null) {
6300                return null;
6301            }
6302            return r.intent.getComponent();
6303        }
6304    }
6305
6306    @Override
6307    public String getPackageForToken(IBinder token) {
6308        synchronized(this) {
6309            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6310            if (r == null) {
6311                return null;
6312            }
6313            return r.packageName;
6314        }
6315    }
6316
6317    @Override
6318    public IIntentSender getIntentSender(int type,
6319            String packageName, IBinder token, String resultWho,
6320            int requestCode, Intent[] intents, String[] resolvedTypes,
6321            int flags, Bundle options, int userId) {
6322        enforceNotIsolatedCaller("getIntentSender");
6323        // Refuse possible leaked file descriptors
6324        if (intents != null) {
6325            if (intents.length < 1) {
6326                throw new IllegalArgumentException("Intents array length must be >= 1");
6327            }
6328            for (int i=0; i<intents.length; i++) {
6329                Intent intent = intents[i];
6330                if (intent != null) {
6331                    if (intent.hasFileDescriptors()) {
6332                        throw new IllegalArgumentException("File descriptors passed in Intent");
6333                    }
6334                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6335                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6336                        throw new IllegalArgumentException(
6337                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6338                    }
6339                    intents[i] = new Intent(intent);
6340                }
6341            }
6342            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6343                throw new IllegalArgumentException(
6344                        "Intent array length does not match resolvedTypes length");
6345            }
6346        }
6347        if (options != null) {
6348            if (options.hasFileDescriptors()) {
6349                throw new IllegalArgumentException("File descriptors passed in options");
6350            }
6351        }
6352
6353        synchronized(this) {
6354            int callingUid = Binder.getCallingUid();
6355            int origUserId = userId;
6356            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6357                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6358                    ALLOW_NON_FULL, "getIntentSender", null);
6359            if (origUserId == UserHandle.USER_CURRENT) {
6360                // We don't want to evaluate this until the pending intent is
6361                // actually executed.  However, we do want to always do the
6362                // security checking for it above.
6363                userId = UserHandle.USER_CURRENT;
6364            }
6365            try {
6366                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6367                    int uid = AppGlobals.getPackageManager()
6368                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6369                    if (!UserHandle.isSameApp(callingUid, uid)) {
6370                        String msg = "Permission Denial: getIntentSender() from pid="
6371                            + Binder.getCallingPid()
6372                            + ", uid=" + Binder.getCallingUid()
6373                            + ", (need uid=" + uid + ")"
6374                            + " is not allowed to send as package " + packageName;
6375                        Slog.w(TAG, msg);
6376                        throw new SecurityException(msg);
6377                    }
6378                }
6379
6380                return getIntentSenderLocked(type, packageName, callingUid, userId,
6381                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6382
6383            } catch (RemoteException e) {
6384                throw new SecurityException(e);
6385            }
6386        }
6387    }
6388
6389    IIntentSender getIntentSenderLocked(int type, String packageName,
6390            int callingUid, int userId, IBinder token, String resultWho,
6391            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6392            Bundle options) {
6393        if (DEBUG_MU)
6394            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6395        ActivityRecord activity = null;
6396        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6397            activity = ActivityRecord.isInStackLocked(token);
6398            if (activity == null) {
6399                return null;
6400            }
6401            if (activity.finishing) {
6402                return null;
6403            }
6404        }
6405
6406        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6407        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6408        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6409        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6410                |PendingIntent.FLAG_UPDATE_CURRENT);
6411
6412        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6413                type, packageName, activity, resultWho,
6414                requestCode, intents, resolvedTypes, flags, options, userId);
6415        WeakReference<PendingIntentRecord> ref;
6416        ref = mIntentSenderRecords.get(key);
6417        PendingIntentRecord rec = ref != null ? ref.get() : null;
6418        if (rec != null) {
6419            if (!cancelCurrent) {
6420                if (updateCurrent) {
6421                    if (rec.key.requestIntent != null) {
6422                        rec.key.requestIntent.replaceExtras(intents != null ?
6423                                intents[intents.length - 1] : null);
6424                    }
6425                    if (intents != null) {
6426                        intents[intents.length-1] = rec.key.requestIntent;
6427                        rec.key.allIntents = intents;
6428                        rec.key.allResolvedTypes = resolvedTypes;
6429                    } else {
6430                        rec.key.allIntents = null;
6431                        rec.key.allResolvedTypes = null;
6432                    }
6433                }
6434                return rec;
6435            }
6436            rec.canceled = true;
6437            mIntentSenderRecords.remove(key);
6438        }
6439        if (noCreate) {
6440            return rec;
6441        }
6442        rec = new PendingIntentRecord(this, key, callingUid);
6443        mIntentSenderRecords.put(key, rec.ref);
6444        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6445            if (activity.pendingResults == null) {
6446                activity.pendingResults
6447                        = new HashSet<WeakReference<PendingIntentRecord>>();
6448            }
6449            activity.pendingResults.add(rec.ref);
6450        }
6451        return rec;
6452    }
6453
6454    @Override
6455    public void cancelIntentSender(IIntentSender sender) {
6456        if (!(sender instanceof PendingIntentRecord)) {
6457            return;
6458        }
6459        synchronized(this) {
6460            PendingIntentRecord rec = (PendingIntentRecord)sender;
6461            try {
6462                int uid = AppGlobals.getPackageManager()
6463                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6464                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6465                    String msg = "Permission Denial: cancelIntentSender() from pid="
6466                        + Binder.getCallingPid()
6467                        + ", uid=" + Binder.getCallingUid()
6468                        + " is not allowed to cancel packges "
6469                        + rec.key.packageName;
6470                    Slog.w(TAG, msg);
6471                    throw new SecurityException(msg);
6472                }
6473            } catch (RemoteException e) {
6474                throw new SecurityException(e);
6475            }
6476            cancelIntentSenderLocked(rec, true);
6477        }
6478    }
6479
6480    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6481        rec.canceled = true;
6482        mIntentSenderRecords.remove(rec.key);
6483        if (cleanActivity && rec.key.activity != null) {
6484            rec.key.activity.pendingResults.remove(rec.ref);
6485        }
6486    }
6487
6488    @Override
6489    public String getPackageForIntentSender(IIntentSender pendingResult) {
6490        if (!(pendingResult instanceof PendingIntentRecord)) {
6491            return null;
6492        }
6493        try {
6494            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6495            return res.key.packageName;
6496        } catch (ClassCastException e) {
6497        }
6498        return null;
6499    }
6500
6501    @Override
6502    public int getUidForIntentSender(IIntentSender sender) {
6503        if (sender instanceof PendingIntentRecord) {
6504            try {
6505                PendingIntentRecord res = (PendingIntentRecord)sender;
6506                return res.uid;
6507            } catch (ClassCastException e) {
6508            }
6509        }
6510        return -1;
6511    }
6512
6513    @Override
6514    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6515        if (!(pendingResult instanceof PendingIntentRecord)) {
6516            return false;
6517        }
6518        try {
6519            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6520            if (res.key.allIntents == null) {
6521                return false;
6522            }
6523            for (int i=0; i<res.key.allIntents.length; i++) {
6524                Intent intent = res.key.allIntents[i];
6525                if (intent.getPackage() != null && intent.getComponent() != null) {
6526                    return false;
6527                }
6528            }
6529            return true;
6530        } catch (ClassCastException e) {
6531        }
6532        return false;
6533    }
6534
6535    @Override
6536    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6537        if (!(pendingResult instanceof PendingIntentRecord)) {
6538            return false;
6539        }
6540        try {
6541            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6542            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6543                return true;
6544            }
6545            return false;
6546        } catch (ClassCastException e) {
6547        }
6548        return false;
6549    }
6550
6551    @Override
6552    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6553        if (!(pendingResult instanceof PendingIntentRecord)) {
6554            return null;
6555        }
6556        try {
6557            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6558            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6559        } catch (ClassCastException e) {
6560        }
6561        return null;
6562    }
6563
6564    @Override
6565    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6566        if (!(pendingResult instanceof PendingIntentRecord)) {
6567            return null;
6568        }
6569        try {
6570            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6571            Intent intent = res.key.requestIntent;
6572            if (intent != null) {
6573                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6574                        || res.lastTagPrefix.equals(prefix))) {
6575                    return res.lastTag;
6576                }
6577                res.lastTagPrefix = prefix;
6578                StringBuilder sb = new StringBuilder(128);
6579                if (prefix != null) {
6580                    sb.append(prefix);
6581                }
6582                if (intent.getAction() != null) {
6583                    sb.append(intent.getAction());
6584                } else if (intent.getComponent() != null) {
6585                    intent.getComponent().appendShortString(sb);
6586                } else {
6587                    sb.append("?");
6588                }
6589                return res.lastTag = sb.toString();
6590            }
6591        } catch (ClassCastException e) {
6592        }
6593        return null;
6594    }
6595
6596    @Override
6597    public void setProcessLimit(int max) {
6598        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6599                "setProcessLimit()");
6600        synchronized (this) {
6601            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6602            mProcessLimitOverride = max;
6603        }
6604        trimApplications();
6605    }
6606
6607    @Override
6608    public int getProcessLimit() {
6609        synchronized (this) {
6610            return mProcessLimitOverride;
6611        }
6612    }
6613
6614    void foregroundTokenDied(ForegroundToken token) {
6615        synchronized (ActivityManagerService.this) {
6616            synchronized (mPidsSelfLocked) {
6617                ForegroundToken cur
6618                    = mForegroundProcesses.get(token.pid);
6619                if (cur != token) {
6620                    return;
6621                }
6622                mForegroundProcesses.remove(token.pid);
6623                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6624                if (pr == null) {
6625                    return;
6626                }
6627                pr.forcingToForeground = null;
6628                updateProcessForegroundLocked(pr, false, false);
6629            }
6630            updateOomAdjLocked();
6631        }
6632    }
6633
6634    @Override
6635    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6636        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6637                "setProcessForeground()");
6638        synchronized(this) {
6639            boolean changed = false;
6640
6641            synchronized (mPidsSelfLocked) {
6642                ProcessRecord pr = mPidsSelfLocked.get(pid);
6643                if (pr == null && isForeground) {
6644                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6645                    return;
6646                }
6647                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6648                if (oldToken != null) {
6649                    oldToken.token.unlinkToDeath(oldToken, 0);
6650                    mForegroundProcesses.remove(pid);
6651                    if (pr != null) {
6652                        pr.forcingToForeground = null;
6653                    }
6654                    changed = true;
6655                }
6656                if (isForeground && token != null) {
6657                    ForegroundToken newToken = new ForegroundToken() {
6658                        @Override
6659                        public void binderDied() {
6660                            foregroundTokenDied(this);
6661                        }
6662                    };
6663                    newToken.pid = pid;
6664                    newToken.token = token;
6665                    try {
6666                        token.linkToDeath(newToken, 0);
6667                        mForegroundProcesses.put(pid, newToken);
6668                        pr.forcingToForeground = token;
6669                        changed = true;
6670                    } catch (RemoteException e) {
6671                        // If the process died while doing this, we will later
6672                        // do the cleanup with the process death link.
6673                    }
6674                }
6675            }
6676
6677            if (changed) {
6678                updateOomAdjLocked();
6679            }
6680        }
6681    }
6682
6683    // =========================================================
6684    // PERMISSIONS
6685    // =========================================================
6686
6687    static class PermissionController extends IPermissionController.Stub {
6688        ActivityManagerService mActivityManagerService;
6689        PermissionController(ActivityManagerService activityManagerService) {
6690            mActivityManagerService = activityManagerService;
6691        }
6692
6693        @Override
6694        public boolean checkPermission(String permission, int pid, int uid) {
6695            return mActivityManagerService.checkPermission(permission, pid,
6696                    uid) == PackageManager.PERMISSION_GRANTED;
6697        }
6698    }
6699
6700    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6701        @Override
6702        public int checkComponentPermission(String permission, int pid, int uid,
6703                int owningUid, boolean exported) {
6704            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6705                    owningUid, exported);
6706        }
6707
6708        @Override
6709        public Object getAMSLock() {
6710            return ActivityManagerService.this;
6711        }
6712    }
6713
6714    /**
6715     * This can be called with or without the global lock held.
6716     */
6717    int checkComponentPermission(String permission, int pid, int uid,
6718            int owningUid, boolean exported) {
6719        // We might be performing an operation on behalf of an indirect binder
6720        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6721        // client identity accordingly before proceeding.
6722        Identity tlsIdentity = sCallerIdentity.get();
6723        if (tlsIdentity != null) {
6724            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6725                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6726            uid = tlsIdentity.uid;
6727            pid = tlsIdentity.pid;
6728        }
6729
6730        if (pid == MY_PID) {
6731            return PackageManager.PERMISSION_GRANTED;
6732        }
6733
6734        return ActivityManager.checkComponentPermission(permission, uid,
6735                owningUid, exported);
6736    }
6737
6738    /**
6739     * As the only public entry point for permissions checking, this method
6740     * can enforce the semantic that requesting a check on a null global
6741     * permission is automatically denied.  (Internally a null permission
6742     * string is used when calling {@link #checkComponentPermission} in cases
6743     * when only uid-based security is needed.)
6744     *
6745     * This can be called with or without the global lock held.
6746     */
6747    @Override
6748    public int checkPermission(String permission, int pid, int uid) {
6749        if (permission == null) {
6750            return PackageManager.PERMISSION_DENIED;
6751        }
6752        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6753    }
6754
6755    /**
6756     * Binder IPC calls go through the public entry point.
6757     * This can be called with or without the global lock held.
6758     */
6759    int checkCallingPermission(String permission) {
6760        return checkPermission(permission,
6761                Binder.getCallingPid(),
6762                UserHandle.getAppId(Binder.getCallingUid()));
6763    }
6764
6765    /**
6766     * This can be called with or without the global lock held.
6767     */
6768    void enforceCallingPermission(String permission, String func) {
6769        if (checkCallingPermission(permission)
6770                == PackageManager.PERMISSION_GRANTED) {
6771            return;
6772        }
6773
6774        String msg = "Permission Denial: " + func + " from pid="
6775                + Binder.getCallingPid()
6776                + ", uid=" + Binder.getCallingUid()
6777                + " requires " + permission;
6778        Slog.w(TAG, msg);
6779        throw new SecurityException(msg);
6780    }
6781
6782    /**
6783     * Determine if UID is holding permissions required to access {@link Uri} in
6784     * the given {@link ProviderInfo}. Final permission checking is always done
6785     * in {@link ContentProvider}.
6786     */
6787    private final boolean checkHoldingPermissionsLocked(
6788            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6789        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6790                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6791        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6792            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6793                    != PERMISSION_GRANTED) {
6794                return false;
6795            }
6796        }
6797        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6798    }
6799
6800    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6801            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6802        if (pi.applicationInfo.uid == uid) {
6803            return true;
6804        } else if (!pi.exported) {
6805            return false;
6806        }
6807
6808        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6809        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6810        try {
6811            // check if target holds top-level <provider> permissions
6812            if (!readMet && pi.readPermission != null && considerUidPermissions
6813                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6814                readMet = true;
6815            }
6816            if (!writeMet && pi.writePermission != null && considerUidPermissions
6817                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6818                writeMet = true;
6819            }
6820
6821            // track if unprotected read/write is allowed; any denied
6822            // <path-permission> below removes this ability
6823            boolean allowDefaultRead = pi.readPermission == null;
6824            boolean allowDefaultWrite = pi.writePermission == null;
6825
6826            // check if target holds any <path-permission> that match uri
6827            final PathPermission[] pps = pi.pathPermissions;
6828            if (pps != null) {
6829                final String path = grantUri.uri.getPath();
6830                int i = pps.length;
6831                while (i > 0 && (!readMet || !writeMet)) {
6832                    i--;
6833                    PathPermission pp = pps[i];
6834                    if (pp.match(path)) {
6835                        if (!readMet) {
6836                            final String pprperm = pp.getReadPermission();
6837                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6838                                    + pprperm + " for " + pp.getPath()
6839                                    + ": match=" + pp.match(path)
6840                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6841                            if (pprperm != null) {
6842                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6843                                        == PERMISSION_GRANTED) {
6844                                    readMet = true;
6845                                } else {
6846                                    allowDefaultRead = false;
6847                                }
6848                            }
6849                        }
6850                        if (!writeMet) {
6851                            final String ppwperm = pp.getWritePermission();
6852                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6853                                    + ppwperm + " for " + pp.getPath()
6854                                    + ": match=" + pp.match(path)
6855                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6856                            if (ppwperm != null) {
6857                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6858                                        == PERMISSION_GRANTED) {
6859                                    writeMet = true;
6860                                } else {
6861                                    allowDefaultWrite = false;
6862                                }
6863                            }
6864                        }
6865                    }
6866                }
6867            }
6868
6869            // grant unprotected <provider> read/write, if not blocked by
6870            // <path-permission> above
6871            if (allowDefaultRead) readMet = true;
6872            if (allowDefaultWrite) writeMet = true;
6873
6874        } catch (RemoteException e) {
6875            return false;
6876        }
6877
6878        return readMet && writeMet;
6879    }
6880
6881    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6882        ProviderInfo pi = null;
6883        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6884        if (cpr != null) {
6885            pi = cpr.info;
6886        } else {
6887            try {
6888                pi = AppGlobals.getPackageManager().resolveContentProvider(
6889                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6890            } catch (RemoteException ex) {
6891            }
6892        }
6893        return pi;
6894    }
6895
6896    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6897        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6898        if (targetUris != null) {
6899            return targetUris.get(grantUri);
6900        }
6901        return null;
6902    }
6903
6904    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6905            String targetPkg, int targetUid, GrantUri grantUri) {
6906        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6907        if (targetUris == null) {
6908            targetUris = Maps.newArrayMap();
6909            mGrantedUriPermissions.put(targetUid, targetUris);
6910        }
6911
6912        UriPermission perm = targetUris.get(grantUri);
6913        if (perm == null) {
6914            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6915            targetUris.put(grantUri, perm);
6916        }
6917
6918        return perm;
6919    }
6920
6921    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6922            final int modeFlags) {
6923        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6924        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6925                : UriPermission.STRENGTH_OWNED;
6926
6927        // Root gets to do everything.
6928        if (uid == 0) {
6929            return true;
6930        }
6931
6932        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6933        if (perms == null) return false;
6934
6935        // First look for exact match
6936        final UriPermission exactPerm = perms.get(grantUri);
6937        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6938            return true;
6939        }
6940
6941        // No exact match, look for prefixes
6942        final int N = perms.size();
6943        for (int i = 0; i < N; i++) {
6944            final UriPermission perm = perms.valueAt(i);
6945            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6946                    && perm.getStrength(modeFlags) >= minStrength) {
6947                return true;
6948            }
6949        }
6950
6951        return false;
6952    }
6953
6954    /**
6955     * @param uri This uri must NOT contain an embedded userId.
6956     * @param userId The userId in which the uri is to be resolved.
6957     */
6958    @Override
6959    public int checkUriPermission(Uri uri, int pid, int uid,
6960            final int modeFlags, int userId) {
6961        enforceNotIsolatedCaller("checkUriPermission");
6962
6963        // Another redirected-binder-call permissions check as in
6964        // {@link checkComponentPermission}.
6965        Identity tlsIdentity = sCallerIdentity.get();
6966        if (tlsIdentity != null) {
6967            uid = tlsIdentity.uid;
6968            pid = tlsIdentity.pid;
6969        }
6970
6971        // Our own process gets to do everything.
6972        if (pid == MY_PID) {
6973            return PackageManager.PERMISSION_GRANTED;
6974        }
6975        synchronized (this) {
6976            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6977                    ? PackageManager.PERMISSION_GRANTED
6978                    : PackageManager.PERMISSION_DENIED;
6979        }
6980    }
6981
6982    /**
6983     * Check if the targetPkg can be granted permission to access uri by
6984     * the callingUid using the given modeFlags.  Throws a security exception
6985     * if callingUid is not allowed to do this.  Returns the uid of the target
6986     * if the URI permission grant should be performed; returns -1 if it is not
6987     * needed (for example targetPkg already has permission to access the URI).
6988     * If you already know the uid of the target, you can supply it in
6989     * lastTargetUid else set that to -1.
6990     */
6991    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6992            final int modeFlags, int lastTargetUid) {
6993        if (!Intent.isAccessUriMode(modeFlags)) {
6994            return -1;
6995        }
6996
6997        if (targetPkg != null) {
6998            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6999                    "Checking grant " + targetPkg + " permission to " + grantUri);
7000        }
7001
7002        final IPackageManager pm = AppGlobals.getPackageManager();
7003
7004        // If this is not a content: uri, we can't do anything with it.
7005        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7006            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7007                    "Can't grant URI permission for non-content URI: " + grantUri);
7008            return -1;
7009        }
7010
7011        final String authority = grantUri.uri.getAuthority();
7012        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7013        if (pi == null) {
7014            Slog.w(TAG, "No content provider found for permission check: " +
7015                    grantUri.uri.toSafeString());
7016            return -1;
7017        }
7018
7019        int targetUid = lastTargetUid;
7020        if (targetUid < 0 && targetPkg != null) {
7021            try {
7022                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7023                if (targetUid < 0) {
7024                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7025                            "Can't grant URI permission no uid for: " + targetPkg);
7026                    return -1;
7027                }
7028            } catch (RemoteException ex) {
7029                return -1;
7030            }
7031        }
7032
7033        if (targetUid >= 0) {
7034            // First...  does the target actually need this permission?
7035            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7036                // No need to grant the target this permission.
7037                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7038                        "Target " + targetPkg + " already has full permission to " + grantUri);
7039                return -1;
7040            }
7041        } else {
7042            // First...  there is no target package, so can anyone access it?
7043            boolean allowed = pi.exported;
7044            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7045                if (pi.readPermission != null) {
7046                    allowed = false;
7047                }
7048            }
7049            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7050                if (pi.writePermission != null) {
7051                    allowed = false;
7052                }
7053            }
7054            if (allowed) {
7055                return -1;
7056            }
7057        }
7058
7059        /* There is a special cross user grant if:
7060         * - The target is on another user.
7061         * - Apps on the current user can access the uri without any uid permissions.
7062         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7063         * grant uri permissions.
7064         */
7065        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7066                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7067                modeFlags, false /*without considering the uid permissions*/);
7068
7069        // Second...  is the provider allowing granting of URI permissions?
7070        if (!specialCrossUserGrant) {
7071            if (!pi.grantUriPermissions) {
7072                throw new SecurityException("Provider " + pi.packageName
7073                        + "/" + pi.name
7074                        + " does not allow granting of Uri permissions (uri "
7075                        + grantUri + ")");
7076            }
7077            if (pi.uriPermissionPatterns != null) {
7078                final int N = pi.uriPermissionPatterns.length;
7079                boolean allowed = false;
7080                for (int i=0; i<N; i++) {
7081                    if (pi.uriPermissionPatterns[i] != null
7082                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7083                        allowed = true;
7084                        break;
7085                    }
7086                }
7087                if (!allowed) {
7088                    throw new SecurityException("Provider " + pi.packageName
7089                            + "/" + pi.name
7090                            + " does not allow granting of permission to path of Uri "
7091                            + grantUri);
7092                }
7093            }
7094        }
7095
7096        // Third...  does the caller itself have permission to access
7097        // this uri?
7098        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7099            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7100                // Require they hold a strong enough Uri permission
7101                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7102                    throw new SecurityException("Uid " + callingUid
7103                            + " does not have permission to uri " + grantUri);
7104                }
7105            }
7106        }
7107        return targetUid;
7108    }
7109
7110    /**
7111     * @param uri This uri must NOT contain an embedded userId.
7112     * @param userId The userId in which the uri is to be resolved.
7113     */
7114    @Override
7115    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7116            final int modeFlags, int userId) {
7117        enforceNotIsolatedCaller("checkGrantUriPermission");
7118        synchronized(this) {
7119            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7120                    new GrantUri(userId, uri, false), modeFlags, -1);
7121        }
7122    }
7123
7124    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7125            final int modeFlags, UriPermissionOwner owner) {
7126        if (!Intent.isAccessUriMode(modeFlags)) {
7127            return;
7128        }
7129
7130        // So here we are: the caller has the assumed permission
7131        // to the uri, and the target doesn't.  Let's now give this to
7132        // the target.
7133
7134        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7135                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7136
7137        final String authority = grantUri.uri.getAuthority();
7138        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7139        if (pi == null) {
7140            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7141            return;
7142        }
7143
7144        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7145            grantUri.prefix = true;
7146        }
7147        final UriPermission perm = findOrCreateUriPermissionLocked(
7148                pi.packageName, targetPkg, targetUid, grantUri);
7149        perm.grantModes(modeFlags, owner);
7150    }
7151
7152    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7153            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7154        if (targetPkg == null) {
7155            throw new NullPointerException("targetPkg");
7156        }
7157        int targetUid;
7158        final IPackageManager pm = AppGlobals.getPackageManager();
7159        try {
7160            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7161        } catch (RemoteException ex) {
7162            return;
7163        }
7164
7165        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7166                targetUid);
7167        if (targetUid < 0) {
7168            return;
7169        }
7170
7171        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7172                owner);
7173    }
7174
7175    static class NeededUriGrants extends ArrayList<GrantUri> {
7176        final String targetPkg;
7177        final int targetUid;
7178        final int flags;
7179
7180        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7181            this.targetPkg = targetPkg;
7182            this.targetUid = targetUid;
7183            this.flags = flags;
7184        }
7185    }
7186
7187    /**
7188     * Like checkGrantUriPermissionLocked, but takes an Intent.
7189     */
7190    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7191            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7192        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7193                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7194                + " clip=" + (intent != null ? intent.getClipData() : null)
7195                + " from " + intent + "; flags=0x"
7196                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7197
7198        if (targetPkg == null) {
7199            throw new NullPointerException("targetPkg");
7200        }
7201
7202        if (intent == null) {
7203            return null;
7204        }
7205        Uri data = intent.getData();
7206        ClipData clip = intent.getClipData();
7207        if (data == null && clip == null) {
7208            return null;
7209        }
7210        // Default userId for uris in the intent (if they don't specify it themselves)
7211        int contentUserHint = intent.getContentUserHint();
7212        if (contentUserHint == UserHandle.USER_CURRENT) {
7213            contentUserHint = UserHandle.getUserId(callingUid);
7214        }
7215        final IPackageManager pm = AppGlobals.getPackageManager();
7216        int targetUid;
7217        if (needed != null) {
7218            targetUid = needed.targetUid;
7219        } else {
7220            try {
7221                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7222            } catch (RemoteException ex) {
7223                return null;
7224            }
7225            if (targetUid < 0) {
7226                if (DEBUG_URI_PERMISSION) {
7227                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7228                            + " on user " + targetUserId);
7229                }
7230                return null;
7231            }
7232        }
7233        if (data != null) {
7234            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7235            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7236                    targetUid);
7237            if (targetUid > 0) {
7238                if (needed == null) {
7239                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7240                }
7241                needed.add(grantUri);
7242            }
7243        }
7244        if (clip != null) {
7245            for (int i=0; i<clip.getItemCount(); i++) {
7246                Uri uri = clip.getItemAt(i).getUri();
7247                if (uri != null) {
7248                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7249                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7250                            targetUid);
7251                    if (targetUid > 0) {
7252                        if (needed == null) {
7253                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7254                        }
7255                        needed.add(grantUri);
7256                    }
7257                } else {
7258                    Intent clipIntent = clip.getItemAt(i).getIntent();
7259                    if (clipIntent != null) {
7260                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7261                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7262                        if (newNeeded != null) {
7263                            needed = newNeeded;
7264                        }
7265                    }
7266                }
7267            }
7268        }
7269
7270        return needed;
7271    }
7272
7273    /**
7274     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7275     */
7276    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7277            UriPermissionOwner owner) {
7278        if (needed != null) {
7279            for (int i=0; i<needed.size(); i++) {
7280                GrantUri grantUri = needed.get(i);
7281                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7282                        grantUri, needed.flags, owner);
7283            }
7284        }
7285    }
7286
7287    void grantUriPermissionFromIntentLocked(int callingUid,
7288            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7289        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7290                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7291        if (needed == null) {
7292            return;
7293        }
7294
7295        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7296    }
7297
7298    /**
7299     * @param uri This uri must NOT contain an embedded userId.
7300     * @param userId The userId in which the uri is to be resolved.
7301     */
7302    @Override
7303    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7304            final int modeFlags, int userId) {
7305        enforceNotIsolatedCaller("grantUriPermission");
7306        GrantUri grantUri = new GrantUri(userId, uri, false);
7307        synchronized(this) {
7308            final ProcessRecord r = getRecordForAppLocked(caller);
7309            if (r == null) {
7310                throw new SecurityException("Unable to find app for caller "
7311                        + caller
7312                        + " when granting permission to uri " + grantUri);
7313            }
7314            if (targetPkg == null) {
7315                throw new IllegalArgumentException("null target");
7316            }
7317            if (grantUri == null) {
7318                throw new IllegalArgumentException("null uri");
7319            }
7320
7321            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7322                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7323                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7324                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7325
7326            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7327                    UserHandle.getUserId(r.uid));
7328        }
7329    }
7330
7331    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7332        if (perm.modeFlags == 0) {
7333            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7334                    perm.targetUid);
7335            if (perms != null) {
7336                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7337                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7338
7339                perms.remove(perm.uri);
7340                if (perms.isEmpty()) {
7341                    mGrantedUriPermissions.remove(perm.targetUid);
7342                }
7343            }
7344        }
7345    }
7346
7347    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7348        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7349
7350        final IPackageManager pm = AppGlobals.getPackageManager();
7351        final String authority = grantUri.uri.getAuthority();
7352        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7353        if (pi == null) {
7354            Slog.w(TAG, "No content provider found for permission revoke: "
7355                    + grantUri.toSafeString());
7356            return;
7357        }
7358
7359        // Does the caller have this permission on the URI?
7360        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7361            // If they don't have direct access to the URI, then revoke any
7362            // ownerless URI permissions that have been granted to them.
7363            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7364            if (perms != null) {
7365                boolean persistChanged = false;
7366                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7367                    final UriPermission perm = it.next();
7368                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7369                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7370                        if (DEBUG_URI_PERMISSION)
7371                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7372                                    " permission to " + perm.uri);
7373                        persistChanged |= perm.revokeModes(
7374                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7375                        if (perm.modeFlags == 0) {
7376                            it.remove();
7377                        }
7378                    }
7379                }
7380                if (perms.isEmpty()) {
7381                    mGrantedUriPermissions.remove(callingUid);
7382                }
7383                if (persistChanged) {
7384                    schedulePersistUriGrants();
7385                }
7386            }
7387            return;
7388        }
7389
7390        boolean persistChanged = false;
7391
7392        // Go through all of the permissions and remove any that match.
7393        int N = mGrantedUriPermissions.size();
7394        for (int i = 0; i < N; i++) {
7395            final int targetUid = mGrantedUriPermissions.keyAt(i);
7396            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7397
7398            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7399                final UriPermission perm = it.next();
7400                if (perm.uri.sourceUserId == grantUri.sourceUserId
7401                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7402                    if (DEBUG_URI_PERMISSION)
7403                        Slog.v(TAG,
7404                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7405                    persistChanged |= perm.revokeModes(
7406                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7407                    if (perm.modeFlags == 0) {
7408                        it.remove();
7409                    }
7410                }
7411            }
7412
7413            if (perms.isEmpty()) {
7414                mGrantedUriPermissions.remove(targetUid);
7415                N--;
7416                i--;
7417            }
7418        }
7419
7420        if (persistChanged) {
7421            schedulePersistUriGrants();
7422        }
7423    }
7424
7425    /**
7426     * @param uri This uri must NOT contain an embedded userId.
7427     * @param userId The userId in which the uri is to be resolved.
7428     */
7429    @Override
7430    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7431            int userId) {
7432        enforceNotIsolatedCaller("revokeUriPermission");
7433        synchronized(this) {
7434            final ProcessRecord r = getRecordForAppLocked(caller);
7435            if (r == null) {
7436                throw new SecurityException("Unable to find app for caller "
7437                        + caller
7438                        + " when revoking permission to uri " + uri);
7439            }
7440            if (uri == null) {
7441                Slog.w(TAG, "revokeUriPermission: null uri");
7442                return;
7443            }
7444
7445            if (!Intent.isAccessUriMode(modeFlags)) {
7446                return;
7447            }
7448
7449            final IPackageManager pm = AppGlobals.getPackageManager();
7450            final String authority = uri.getAuthority();
7451            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7452            if (pi == null) {
7453                Slog.w(TAG, "No content provider found for permission revoke: "
7454                        + uri.toSafeString());
7455                return;
7456            }
7457
7458            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7459        }
7460    }
7461
7462    /**
7463     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7464     * given package.
7465     *
7466     * @param packageName Package name to match, or {@code null} to apply to all
7467     *            packages.
7468     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7469     *            to all users.
7470     * @param persistable If persistable grants should be removed.
7471     */
7472    private void removeUriPermissionsForPackageLocked(
7473            String packageName, int userHandle, boolean persistable) {
7474        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7475            throw new IllegalArgumentException("Must narrow by either package or user");
7476        }
7477
7478        boolean persistChanged = false;
7479
7480        int N = mGrantedUriPermissions.size();
7481        for (int i = 0; i < N; i++) {
7482            final int targetUid = mGrantedUriPermissions.keyAt(i);
7483            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7484
7485            // Only inspect grants matching user
7486            if (userHandle == UserHandle.USER_ALL
7487                    || userHandle == UserHandle.getUserId(targetUid)) {
7488                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7489                    final UriPermission perm = it.next();
7490
7491                    // Only inspect grants matching package
7492                    if (packageName == null || perm.sourcePkg.equals(packageName)
7493                            || perm.targetPkg.equals(packageName)) {
7494                        persistChanged |= perm.revokeModes(persistable
7495                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7496
7497                        // Only remove when no modes remain; any persisted grants
7498                        // will keep this alive.
7499                        if (perm.modeFlags == 0) {
7500                            it.remove();
7501                        }
7502                    }
7503                }
7504
7505                if (perms.isEmpty()) {
7506                    mGrantedUriPermissions.remove(targetUid);
7507                    N--;
7508                    i--;
7509                }
7510            }
7511        }
7512
7513        if (persistChanged) {
7514            schedulePersistUriGrants();
7515        }
7516    }
7517
7518    @Override
7519    public IBinder newUriPermissionOwner(String name) {
7520        enforceNotIsolatedCaller("newUriPermissionOwner");
7521        synchronized(this) {
7522            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7523            return owner.getExternalTokenLocked();
7524        }
7525    }
7526
7527    /**
7528     * @param uri This uri must NOT contain an embedded userId.
7529     * @param sourceUserId The userId in which the uri is to be resolved.
7530     * @param targetUserId The userId of the app that receives the grant.
7531     */
7532    @Override
7533    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7534            final int modeFlags, int sourceUserId, int targetUserId) {
7535        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7536                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7537        synchronized(this) {
7538            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7539            if (owner == null) {
7540                throw new IllegalArgumentException("Unknown owner: " + token);
7541            }
7542            if (fromUid != Binder.getCallingUid()) {
7543                if (Binder.getCallingUid() != Process.myUid()) {
7544                    // Only system code can grant URI permissions on behalf
7545                    // of other users.
7546                    throw new SecurityException("nice try");
7547                }
7548            }
7549            if (targetPkg == null) {
7550                throw new IllegalArgumentException("null target");
7551            }
7552            if (uri == null) {
7553                throw new IllegalArgumentException("null uri");
7554            }
7555
7556            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7557                    modeFlags, owner, targetUserId);
7558        }
7559    }
7560
7561    /**
7562     * @param uri This uri must NOT contain an embedded userId.
7563     * @param userId The userId in which the uri is to be resolved.
7564     */
7565    @Override
7566    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7567        synchronized(this) {
7568            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7569            if (owner == null) {
7570                throw new IllegalArgumentException("Unknown owner: " + token);
7571            }
7572
7573            if (uri == null) {
7574                owner.removeUriPermissionsLocked(mode);
7575            } else {
7576                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7577            }
7578        }
7579    }
7580
7581    private void schedulePersistUriGrants() {
7582        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7583            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7584                    10 * DateUtils.SECOND_IN_MILLIS);
7585        }
7586    }
7587
7588    private void writeGrantedUriPermissions() {
7589        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7590
7591        // Snapshot permissions so we can persist without lock
7592        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7593        synchronized (this) {
7594            final int size = mGrantedUriPermissions.size();
7595            for (int i = 0; i < size; i++) {
7596                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7597                for (UriPermission perm : perms.values()) {
7598                    if (perm.persistedModeFlags != 0) {
7599                        persist.add(perm.snapshot());
7600                    }
7601                }
7602            }
7603        }
7604
7605        FileOutputStream fos = null;
7606        try {
7607            fos = mGrantFile.startWrite();
7608
7609            XmlSerializer out = new FastXmlSerializer();
7610            out.setOutput(fos, "utf-8");
7611            out.startDocument(null, true);
7612            out.startTag(null, TAG_URI_GRANTS);
7613            for (UriPermission.Snapshot perm : persist) {
7614                out.startTag(null, TAG_URI_GRANT);
7615                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7616                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7617                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7618                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7619                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7620                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7621                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7622                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7623                out.endTag(null, TAG_URI_GRANT);
7624            }
7625            out.endTag(null, TAG_URI_GRANTS);
7626            out.endDocument();
7627
7628            mGrantFile.finishWrite(fos);
7629        } catch (IOException e) {
7630            if (fos != null) {
7631                mGrantFile.failWrite(fos);
7632            }
7633        }
7634    }
7635
7636    private void readGrantedUriPermissionsLocked() {
7637        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7638
7639        final long now = System.currentTimeMillis();
7640
7641        FileInputStream fis = null;
7642        try {
7643            fis = mGrantFile.openRead();
7644            final XmlPullParser in = Xml.newPullParser();
7645            in.setInput(fis, null);
7646
7647            int type;
7648            while ((type = in.next()) != END_DOCUMENT) {
7649                final String tag = in.getName();
7650                if (type == START_TAG) {
7651                    if (TAG_URI_GRANT.equals(tag)) {
7652                        final int sourceUserId;
7653                        final int targetUserId;
7654                        final int userHandle = readIntAttribute(in,
7655                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7656                        if (userHandle != UserHandle.USER_NULL) {
7657                            // For backwards compatibility.
7658                            sourceUserId = userHandle;
7659                            targetUserId = userHandle;
7660                        } else {
7661                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7662                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7663                        }
7664                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7665                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7666                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7667                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7668                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7669                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7670
7671                        // Sanity check that provider still belongs to source package
7672                        final ProviderInfo pi = getProviderInfoLocked(
7673                                uri.getAuthority(), sourceUserId);
7674                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7675                            int targetUid = -1;
7676                            try {
7677                                targetUid = AppGlobals.getPackageManager()
7678                                        .getPackageUid(targetPkg, targetUserId);
7679                            } catch (RemoteException e) {
7680                            }
7681                            if (targetUid != -1) {
7682                                final UriPermission perm = findOrCreateUriPermissionLocked(
7683                                        sourcePkg, targetPkg, targetUid,
7684                                        new GrantUri(sourceUserId, uri, prefix));
7685                                perm.initPersistedModes(modeFlags, createdTime);
7686                            }
7687                        } else {
7688                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7689                                    + " but instead found " + pi);
7690                        }
7691                    }
7692                }
7693            }
7694        } catch (FileNotFoundException e) {
7695            // Missing grants is okay
7696        } catch (IOException e) {
7697            Slog.wtf(TAG, "Failed reading Uri grants", e);
7698        } catch (XmlPullParserException e) {
7699            Slog.wtf(TAG, "Failed reading Uri grants", e);
7700        } finally {
7701            IoUtils.closeQuietly(fis);
7702        }
7703    }
7704
7705    /**
7706     * @param uri This uri must NOT contain an embedded userId.
7707     * @param userId The userId in which the uri is to be resolved.
7708     */
7709    @Override
7710    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7711        enforceNotIsolatedCaller("takePersistableUriPermission");
7712
7713        Preconditions.checkFlagsArgument(modeFlags,
7714                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7715
7716        synchronized (this) {
7717            final int callingUid = Binder.getCallingUid();
7718            boolean persistChanged = false;
7719            GrantUri grantUri = new GrantUri(userId, uri, false);
7720
7721            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7722                    new GrantUri(userId, uri, false));
7723            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7724                    new GrantUri(userId, uri, true));
7725
7726            final boolean exactValid = (exactPerm != null)
7727                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7728            final boolean prefixValid = (prefixPerm != null)
7729                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7730
7731            if (!(exactValid || prefixValid)) {
7732                throw new SecurityException("No persistable permission grants found for UID "
7733                        + callingUid + " and Uri " + grantUri.toSafeString());
7734            }
7735
7736            if (exactValid) {
7737                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7738            }
7739            if (prefixValid) {
7740                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7741            }
7742
7743            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7744
7745            if (persistChanged) {
7746                schedulePersistUriGrants();
7747            }
7748        }
7749    }
7750
7751    /**
7752     * @param uri This uri must NOT contain an embedded userId.
7753     * @param userId The userId in which the uri is to be resolved.
7754     */
7755    @Override
7756    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7757        enforceNotIsolatedCaller("releasePersistableUriPermission");
7758
7759        Preconditions.checkFlagsArgument(modeFlags,
7760                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7761
7762        synchronized (this) {
7763            final int callingUid = Binder.getCallingUid();
7764            boolean persistChanged = false;
7765
7766            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7767                    new GrantUri(userId, uri, false));
7768            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7769                    new GrantUri(userId, uri, true));
7770            if (exactPerm == null && prefixPerm == null) {
7771                throw new SecurityException("No permission grants found for UID " + callingUid
7772                        + " and Uri " + uri.toSafeString());
7773            }
7774
7775            if (exactPerm != null) {
7776                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7777                removeUriPermissionIfNeededLocked(exactPerm);
7778            }
7779            if (prefixPerm != null) {
7780                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7781                removeUriPermissionIfNeededLocked(prefixPerm);
7782            }
7783
7784            if (persistChanged) {
7785                schedulePersistUriGrants();
7786            }
7787        }
7788    }
7789
7790    /**
7791     * Prune any older {@link UriPermission} for the given UID until outstanding
7792     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7793     *
7794     * @return if any mutations occured that require persisting.
7795     */
7796    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7797        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7798        if (perms == null) return false;
7799        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7800
7801        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7802        for (UriPermission perm : perms.values()) {
7803            if (perm.persistedModeFlags != 0) {
7804                persisted.add(perm);
7805            }
7806        }
7807
7808        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7809        if (trimCount <= 0) return false;
7810
7811        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7812        for (int i = 0; i < trimCount; i++) {
7813            final UriPermission perm = persisted.get(i);
7814
7815            if (DEBUG_URI_PERMISSION) {
7816                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7817            }
7818
7819            perm.releasePersistableModes(~0);
7820            removeUriPermissionIfNeededLocked(perm);
7821        }
7822
7823        return true;
7824    }
7825
7826    @Override
7827    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7828            String packageName, boolean incoming) {
7829        enforceNotIsolatedCaller("getPersistedUriPermissions");
7830        Preconditions.checkNotNull(packageName, "packageName");
7831
7832        final int callingUid = Binder.getCallingUid();
7833        final IPackageManager pm = AppGlobals.getPackageManager();
7834        try {
7835            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7836            if (packageUid != callingUid) {
7837                throw new SecurityException(
7838                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7839            }
7840        } catch (RemoteException e) {
7841            throw new SecurityException("Failed to verify package name ownership");
7842        }
7843
7844        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7845        synchronized (this) {
7846            if (incoming) {
7847                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7848                        callingUid);
7849                if (perms == null) {
7850                    Slog.w(TAG, "No permission grants found for " + packageName);
7851                } else {
7852                    for (UriPermission perm : perms.values()) {
7853                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7854                            result.add(perm.buildPersistedPublicApiObject());
7855                        }
7856                    }
7857                }
7858            } else {
7859                final int size = mGrantedUriPermissions.size();
7860                for (int i = 0; i < size; i++) {
7861                    final ArrayMap<GrantUri, UriPermission> perms =
7862                            mGrantedUriPermissions.valueAt(i);
7863                    for (UriPermission perm : perms.values()) {
7864                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7865                            result.add(perm.buildPersistedPublicApiObject());
7866                        }
7867                    }
7868                }
7869            }
7870        }
7871        return new ParceledListSlice<android.content.UriPermission>(result);
7872    }
7873
7874    @Override
7875    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7876        synchronized (this) {
7877            ProcessRecord app =
7878                who != null ? getRecordForAppLocked(who) : null;
7879            if (app == null) return;
7880
7881            Message msg = Message.obtain();
7882            msg.what = WAIT_FOR_DEBUGGER_MSG;
7883            msg.obj = app;
7884            msg.arg1 = waiting ? 1 : 0;
7885            mHandler.sendMessage(msg);
7886        }
7887    }
7888
7889    @Override
7890    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7891        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7892        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7893        outInfo.availMem = Process.getFreeMemory();
7894        outInfo.totalMem = Process.getTotalMemory();
7895        outInfo.threshold = homeAppMem;
7896        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7897        outInfo.hiddenAppThreshold = cachedAppMem;
7898        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7899                ProcessList.SERVICE_ADJ);
7900        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7901                ProcessList.VISIBLE_APP_ADJ);
7902        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7903                ProcessList.FOREGROUND_APP_ADJ);
7904    }
7905
7906    // =========================================================
7907    // TASK MANAGEMENT
7908    // =========================================================
7909
7910    @Override
7911    public List<IAppTask> getAppTasks(String callingPackage) {
7912        int callingUid = Binder.getCallingUid();
7913        long ident = Binder.clearCallingIdentity();
7914
7915        synchronized(this) {
7916            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7917            try {
7918                if (localLOGV) Slog.v(TAG, "getAppTasks");
7919
7920                final int N = mRecentTasks.size();
7921                for (int i = 0; i < N; i++) {
7922                    TaskRecord tr = mRecentTasks.get(i);
7923                    // Skip tasks that do not match the caller.  We don't need to verify
7924                    // callingPackage, because we are also limiting to callingUid and know
7925                    // that will limit to the correct security sandbox.
7926                    if (tr.effectiveUid != callingUid) {
7927                        continue;
7928                    }
7929                    Intent intent = tr.getBaseIntent();
7930                    if (intent == null ||
7931                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7932                        continue;
7933                    }
7934                    ActivityManager.RecentTaskInfo taskInfo =
7935                            createRecentTaskInfoFromTaskRecord(tr);
7936                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7937                    list.add(taskImpl);
7938                }
7939            } finally {
7940                Binder.restoreCallingIdentity(ident);
7941            }
7942            return list;
7943        }
7944    }
7945
7946    @Override
7947    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7948        final int callingUid = Binder.getCallingUid();
7949        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7950
7951        synchronized(this) {
7952            if (localLOGV) Slog.v(
7953                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7954
7955            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
7956                    callingUid);
7957
7958            // TODO: Improve with MRU list from all ActivityStacks.
7959            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7960        }
7961
7962        return list;
7963    }
7964
7965    TaskRecord getMostRecentTask() {
7966        return mRecentTasks.get(0);
7967    }
7968
7969    /**
7970     * Creates a new RecentTaskInfo from a TaskRecord.
7971     */
7972    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7973        // Update the task description to reflect any changes in the task stack
7974        tr.updateTaskDescription();
7975
7976        // Compose the recent task info
7977        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7978        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7979        rti.persistentId = tr.taskId;
7980        rti.baseIntent = new Intent(tr.getBaseIntent());
7981        rti.origActivity = tr.origActivity;
7982        rti.description = tr.lastDescription;
7983        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7984        rti.userId = tr.userId;
7985        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7986        rti.firstActiveTime = tr.firstActiveTime;
7987        rti.lastActiveTime = tr.lastActiveTime;
7988        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7989        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7990        return rti;
7991    }
7992
7993    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
7994        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
7995                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
7996        if (!allowed) {
7997            if (checkPermission(android.Manifest.permission.GET_TASKS,
7998                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
7999                // Temporary compatibility: some existing apps on the system image may
8000                // still be requesting the old permission and not switched to the new
8001                // one; if so, we'll still allow them full access.  This means we need
8002                // to see if they are holding the old permission and are a system app.
8003                try {
8004                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8005                        allowed = true;
8006                        Slog.w(TAG, caller + ": caller " + callingUid
8007                                + " is using old GET_TASKS but privileged; allowing");
8008                    }
8009                } catch (RemoteException e) {
8010                }
8011            }
8012        }
8013        if (!allowed) {
8014            Slog.w(TAG, caller + ": caller " + callingUid
8015                    + " does not hold GET_TASKS; limiting output");
8016        }
8017        return allowed;
8018    }
8019
8020    @Override
8021    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8022        final int callingUid = Binder.getCallingUid();
8023        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8024                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8025
8026        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8027        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8028        synchronized (this) {
8029            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8030                    callingUid);
8031            final boolean detailed = checkCallingPermission(
8032                    android.Manifest.permission.GET_DETAILED_TASKS)
8033                    == PackageManager.PERMISSION_GRANTED;
8034
8035            final int N = mRecentTasks.size();
8036            ArrayList<ActivityManager.RecentTaskInfo> res
8037                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8038                            maxNum < N ? maxNum : N);
8039
8040            final Set<Integer> includedUsers;
8041            if (includeProfiles) {
8042                includedUsers = getProfileIdsLocked(userId);
8043            } else {
8044                includedUsers = new HashSet<Integer>();
8045            }
8046            includedUsers.add(Integer.valueOf(userId));
8047
8048            for (int i=0; i<N && maxNum > 0; i++) {
8049                TaskRecord tr = mRecentTasks.get(i);
8050                // Only add calling user or related users recent tasks
8051                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8052                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8053                    continue;
8054                }
8055
8056                // Return the entry if desired by the caller.  We always return
8057                // the first entry, because callers always expect this to be the
8058                // foreground app.  We may filter others if the caller has
8059                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8060                // we should exclude the entry.
8061
8062                if (i == 0
8063                        || withExcluded
8064                        || (tr.intent == null)
8065                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8066                                == 0)) {
8067                    if (!allowed) {
8068                        // If the caller doesn't have the GET_TASKS permission, then only
8069                        // allow them to see a small subset of tasks -- their own and home.
8070                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8071                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8072                            continue;
8073                        }
8074                    }
8075                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8076                        if (tr.stack != null && tr.stack.isHomeStack()) {
8077                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8078                            continue;
8079                        }
8080                    }
8081                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8082                        // Don't include auto remove tasks that are finished or finishing.
8083                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8084                                + tr);
8085                        continue;
8086                    }
8087                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8088                            && !tr.isAvailable) {
8089                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8090                        continue;
8091                    }
8092
8093                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8094                    if (!detailed) {
8095                        rti.baseIntent.replaceExtras((Bundle)null);
8096                    }
8097
8098                    res.add(rti);
8099                    maxNum--;
8100                }
8101            }
8102            return res;
8103        }
8104    }
8105
8106    private TaskRecord taskForIdLocked(int id) {
8107        final TaskRecord task = recentTaskForIdLocked(id);
8108        if (task != null) {
8109            return task;
8110        }
8111
8112        // Don't give up. Sometimes it just hasn't made it to recents yet.
8113        return mStackSupervisor.anyTaskForIdLocked(id);
8114    }
8115
8116    private TaskRecord recentTaskForIdLocked(int id) {
8117        final int N = mRecentTasks.size();
8118            for (int i=0; i<N; i++) {
8119                TaskRecord tr = mRecentTasks.get(i);
8120                if (tr.taskId == id) {
8121                    return tr;
8122                }
8123            }
8124            return null;
8125    }
8126
8127    @Override
8128    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8129        synchronized (this) {
8130            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8131                    "getTaskThumbnail()");
8132            TaskRecord tr = recentTaskForIdLocked(id);
8133            if (tr != null) {
8134                return tr.getTaskThumbnailLocked();
8135            }
8136        }
8137        return null;
8138    }
8139
8140    @Override
8141    public int addAppTask(IBinder activityToken, Intent intent,
8142            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8143        final int callingUid = Binder.getCallingUid();
8144        final long callingIdent = Binder.clearCallingIdentity();
8145
8146        try {
8147            synchronized (this) {
8148                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8149                if (r == null) {
8150                    throw new IllegalArgumentException("Activity does not exist; token="
8151                            + activityToken);
8152                }
8153                ComponentName comp = intent.getComponent();
8154                if (comp == null) {
8155                    throw new IllegalArgumentException("Intent " + intent
8156                            + " must specify explicit component");
8157                }
8158                if (thumbnail.getWidth() != mThumbnailWidth
8159                        || thumbnail.getHeight() != mThumbnailHeight) {
8160                    throw new IllegalArgumentException("Bad thumbnail size: got "
8161                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8162                            + mThumbnailWidth + "x" + mThumbnailHeight);
8163                }
8164                if (intent.getSelector() != null) {
8165                    intent.setSelector(null);
8166                }
8167                if (intent.getSourceBounds() != null) {
8168                    intent.setSourceBounds(null);
8169                }
8170                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8171                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8172                        // The caller has added this as an auto-remove task...  that makes no
8173                        // sense, so turn off auto-remove.
8174                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8175                    }
8176                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8177                    // Must be a new task.
8178                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8179                }
8180                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8181                    mLastAddedTaskActivity = null;
8182                }
8183                ActivityInfo ainfo = mLastAddedTaskActivity;
8184                if (ainfo == null) {
8185                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8186                            comp, 0, UserHandle.getUserId(callingUid));
8187                    if (ainfo.applicationInfo.uid != callingUid) {
8188                        throw new SecurityException(
8189                                "Can't add task for another application: target uid="
8190                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8191                    }
8192                }
8193
8194                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8195                        intent, description);
8196
8197                int trimIdx = trimRecentsForTask(task, false);
8198                if (trimIdx >= 0) {
8199                    // If this would have caused a trim, then we'll abort because that
8200                    // means it would be added at the end of the list but then just removed.
8201                    return -1;
8202                }
8203
8204                final int N = mRecentTasks.size();
8205                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8206                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8207                    tr.removedFromRecents(mTaskPersister);
8208                }
8209
8210                task.inRecents = true;
8211                mRecentTasks.add(task);
8212                r.task.stack.addTask(task, false, false);
8213
8214                task.setLastThumbnail(thumbnail);
8215                task.freeLastThumbnail();
8216
8217                return task.taskId;
8218            }
8219        } finally {
8220            Binder.restoreCallingIdentity(callingIdent);
8221        }
8222    }
8223
8224    @Override
8225    public Point getAppTaskThumbnailSize() {
8226        synchronized (this) {
8227            return new Point(mThumbnailWidth,  mThumbnailHeight);
8228        }
8229    }
8230
8231    @Override
8232    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8233        synchronized (this) {
8234            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8235            if (r != null) {
8236                r.setTaskDescription(td);
8237                r.task.updateTaskDescription();
8238            }
8239        }
8240    }
8241
8242    @Override
8243    public Bitmap getTaskDescriptionIcon(String filename) {
8244        if (!FileUtils.isValidExtFilename(filename)
8245                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8246            throw new IllegalArgumentException("Bad filename: " + filename);
8247        }
8248        return mTaskPersister.getTaskDescriptionIcon(filename);
8249    }
8250
8251    @Override
8252    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8253            throws RemoteException {
8254        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8255                opts.getCustomInPlaceResId() == 0) {
8256            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8257                    "with valid animation");
8258        }
8259        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8260        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8261                opts.getCustomInPlaceResId());
8262        mWindowManager.executeAppTransition();
8263    }
8264
8265    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8266        mRecentTasks.remove(tr);
8267        tr.removedFromRecents(mTaskPersister);
8268        ComponentName component = tr.getBaseIntent().getComponent();
8269        if (component == null) {
8270            Slog.w(TAG, "No component for base intent of task: " + tr);
8271            return;
8272        }
8273
8274        if (!killProcess) {
8275            return;
8276        }
8277
8278        // Determine if the process(es) for this task should be killed.
8279        final String pkg = component.getPackageName();
8280        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8281        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8282        for (int i = 0; i < pmap.size(); i++) {
8283
8284            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8285            for (int j = 0; j < uids.size(); j++) {
8286                ProcessRecord proc = uids.valueAt(j);
8287                if (proc.userId != tr.userId) {
8288                    // Don't kill process for a different user.
8289                    continue;
8290                }
8291                if (proc == mHomeProcess) {
8292                    // Don't kill the home process along with tasks from the same package.
8293                    continue;
8294                }
8295                if (!proc.pkgList.containsKey(pkg)) {
8296                    // Don't kill process that is not associated with this task.
8297                    continue;
8298                }
8299
8300                for (int k = 0; k < proc.activities.size(); k++) {
8301                    TaskRecord otherTask = proc.activities.get(k).task;
8302                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8303                        // Don't kill process(es) that has an activity in a different task that is
8304                        // also in recents.
8305                        return;
8306                    }
8307                }
8308
8309                // Add process to kill list.
8310                procsToKill.add(proc);
8311            }
8312        }
8313
8314        // Find any running services associated with this app and stop if needed.
8315        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8316
8317        // Kill the running processes.
8318        for (int i = 0; i < procsToKill.size(); i++) {
8319            ProcessRecord pr = procsToKill.get(i);
8320            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8321                pr.kill("remove task", true);
8322            } else {
8323                pr.waitingToKill = "remove task";
8324            }
8325        }
8326    }
8327
8328    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8329        // Remove all tasks with activities in the specified package from the list of recent tasks
8330        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8331            TaskRecord tr = mRecentTasks.get(i);
8332            if (tr.userId != userId) continue;
8333
8334            ComponentName cn = tr.intent.getComponent();
8335            if (cn != null && cn.getPackageName().equals(packageName)) {
8336                // If the package name matches, remove the task.
8337                removeTaskByIdLocked(tr.taskId, true);
8338            }
8339        }
8340    }
8341
8342    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8343        final IPackageManager pm = AppGlobals.getPackageManager();
8344        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8345
8346        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8347            TaskRecord tr = mRecentTasks.get(i);
8348            if (tr.userId != userId) continue;
8349
8350            ComponentName cn = tr.intent.getComponent();
8351            if (cn != null && cn.getPackageName().equals(packageName)) {
8352                // Skip if component still exists in the package.
8353                if (componentsKnownToExist.contains(cn)) continue;
8354
8355                try {
8356                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8357                    if (info != null) {
8358                        componentsKnownToExist.add(cn);
8359                    } else {
8360                        removeTaskByIdLocked(tr.taskId, false);
8361                    }
8362                } catch (RemoteException e) {
8363                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8364                }
8365            }
8366        }
8367    }
8368
8369    /**
8370     * Removes the task with the specified task id.
8371     *
8372     * @param taskId Identifier of the task to be removed.
8373     * @param killProcess Kill any process associated with the task if possible.
8374     * @return Returns true if the given task was found and removed.
8375     */
8376    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8377        TaskRecord tr = taskForIdLocked(taskId);
8378        if (tr != null) {
8379            tr.removeTaskActivitiesLocked();
8380            cleanUpRemovedTaskLocked(tr, killProcess);
8381            if (tr.isPersistable) {
8382                notifyTaskPersisterLocked(null, true);
8383            }
8384            return true;
8385        }
8386        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8387        return false;
8388    }
8389
8390    @Override
8391    public boolean removeTask(int taskId) {
8392        synchronized (this) {
8393            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8394                    "removeTask()");
8395            long ident = Binder.clearCallingIdentity();
8396            try {
8397                return removeTaskByIdLocked(taskId, true);
8398            } finally {
8399                Binder.restoreCallingIdentity(ident);
8400            }
8401        }
8402    }
8403
8404    /**
8405     * TODO: Add mController hook
8406     */
8407    @Override
8408    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8409        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8410                "moveTaskToFront()");
8411
8412        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8413        synchronized(this) {
8414            moveTaskToFrontLocked(taskId, flags, options);
8415        }
8416    }
8417
8418    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8419        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8420                Binder.getCallingUid(), -1, -1, "Task to front")) {
8421            ActivityOptions.abort(options);
8422            return;
8423        }
8424        final long origId = Binder.clearCallingIdentity();
8425        try {
8426            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8427            if (task == null) {
8428                return;
8429            }
8430            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8431                mStackSupervisor.showLockTaskToast();
8432                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8433                return;
8434            }
8435            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8436            if (prev != null && prev.isRecentsActivity()) {
8437                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8438            }
8439            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8440        } finally {
8441            Binder.restoreCallingIdentity(origId);
8442        }
8443        ActivityOptions.abort(options);
8444    }
8445
8446    @Override
8447    public void moveTaskToBack(int taskId) {
8448        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8449                "moveTaskToBack()");
8450
8451        synchronized(this) {
8452            TaskRecord tr = taskForIdLocked(taskId);
8453            if (tr != null) {
8454                if (tr == mStackSupervisor.mLockTaskModeTask) {
8455                    mStackSupervisor.showLockTaskToast();
8456                    return;
8457                }
8458                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8459                ActivityStack stack = tr.stack;
8460                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8461                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8462                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8463                        return;
8464                    }
8465                }
8466                final long origId = Binder.clearCallingIdentity();
8467                try {
8468                    stack.moveTaskToBackLocked(taskId, null);
8469                } finally {
8470                    Binder.restoreCallingIdentity(origId);
8471                }
8472            }
8473        }
8474    }
8475
8476    /**
8477     * Moves an activity, and all of the other activities within the same task, to the bottom
8478     * of the history stack.  The activity's order within the task is unchanged.
8479     *
8480     * @param token A reference to the activity we wish to move
8481     * @param nonRoot If false then this only works if the activity is the root
8482     *                of a task; if true it will work for any activity in a task.
8483     * @return Returns true if the move completed, false if not.
8484     */
8485    @Override
8486    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8487        enforceNotIsolatedCaller("moveActivityTaskToBack");
8488        synchronized(this) {
8489            final long origId = Binder.clearCallingIdentity();
8490            try {
8491                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8492                if (taskId >= 0) {
8493                    if ((mStackSupervisor.mLockTaskModeTask != null)
8494                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8495                        mStackSupervisor.showLockTaskToast();
8496                        return false;
8497                    }
8498                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8499                }
8500            } finally {
8501                Binder.restoreCallingIdentity(origId);
8502            }
8503        }
8504        return false;
8505    }
8506
8507    @Override
8508    public void moveTaskBackwards(int task) {
8509        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8510                "moveTaskBackwards()");
8511
8512        synchronized(this) {
8513            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8514                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8515                return;
8516            }
8517            final long origId = Binder.clearCallingIdentity();
8518            moveTaskBackwardsLocked(task);
8519            Binder.restoreCallingIdentity(origId);
8520        }
8521    }
8522
8523    private final void moveTaskBackwardsLocked(int task) {
8524        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8525    }
8526
8527    @Override
8528    public IBinder getHomeActivityToken() throws RemoteException {
8529        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8530                "getHomeActivityToken()");
8531        synchronized (this) {
8532            return mStackSupervisor.getHomeActivityToken();
8533        }
8534    }
8535
8536    @Override
8537    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8538            IActivityContainerCallback callback) throws RemoteException {
8539        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8540                "createActivityContainer()");
8541        synchronized (this) {
8542            if (parentActivityToken == null) {
8543                throw new IllegalArgumentException("parent token must not be null");
8544            }
8545            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8546            if (r == null) {
8547                return null;
8548            }
8549            if (callback == null) {
8550                throw new IllegalArgumentException("callback must not be null");
8551            }
8552            return mStackSupervisor.createActivityContainer(r, callback);
8553        }
8554    }
8555
8556    @Override
8557    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8558        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8559                "deleteActivityContainer()");
8560        synchronized (this) {
8561            mStackSupervisor.deleteActivityContainer(container);
8562        }
8563    }
8564
8565    @Override
8566    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8567            throws RemoteException {
8568        synchronized (this) {
8569            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8570            if (stack != null) {
8571                return stack.mActivityContainer;
8572            }
8573            return null;
8574        }
8575    }
8576
8577    @Override
8578    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8579        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8580                "moveTaskToStack()");
8581        if (stackId == HOME_STACK_ID) {
8582            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8583                    new RuntimeException("here").fillInStackTrace());
8584        }
8585        synchronized (this) {
8586            long ident = Binder.clearCallingIdentity();
8587            try {
8588                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8589                        + stackId + " toTop=" + toTop);
8590                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8591            } finally {
8592                Binder.restoreCallingIdentity(ident);
8593            }
8594        }
8595    }
8596
8597    @Override
8598    public void resizeStack(int stackBoxId, Rect bounds) {
8599        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8600                "resizeStackBox()");
8601        long ident = Binder.clearCallingIdentity();
8602        try {
8603            mWindowManager.resizeStack(stackBoxId, bounds);
8604        } finally {
8605            Binder.restoreCallingIdentity(ident);
8606        }
8607    }
8608
8609    @Override
8610    public List<StackInfo> getAllStackInfos() {
8611        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8612                "getAllStackInfos()");
8613        long ident = Binder.clearCallingIdentity();
8614        try {
8615            synchronized (this) {
8616                return mStackSupervisor.getAllStackInfosLocked();
8617            }
8618        } finally {
8619            Binder.restoreCallingIdentity(ident);
8620        }
8621    }
8622
8623    @Override
8624    public StackInfo getStackInfo(int stackId) {
8625        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8626                "getStackInfo()");
8627        long ident = Binder.clearCallingIdentity();
8628        try {
8629            synchronized (this) {
8630                return mStackSupervisor.getStackInfoLocked(stackId);
8631            }
8632        } finally {
8633            Binder.restoreCallingIdentity(ident);
8634        }
8635    }
8636
8637    @Override
8638    public boolean isInHomeStack(int taskId) {
8639        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8640                "getStackInfo()");
8641        long ident = Binder.clearCallingIdentity();
8642        try {
8643            synchronized (this) {
8644                TaskRecord tr = taskForIdLocked(taskId);
8645                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8646            }
8647        } finally {
8648            Binder.restoreCallingIdentity(ident);
8649        }
8650    }
8651
8652    @Override
8653    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8654        synchronized(this) {
8655            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8656        }
8657    }
8658
8659    private boolean isLockTaskAuthorized(String pkg) {
8660        final DevicePolicyManager dpm = (DevicePolicyManager)
8661                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8662        try {
8663            int uid = mContext.getPackageManager().getPackageUid(pkg,
8664                    Binder.getCallingUserHandle().getIdentifier());
8665            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8666        } catch (NameNotFoundException e) {
8667            return false;
8668        }
8669    }
8670
8671    void startLockTaskMode(TaskRecord task) {
8672        final String pkg;
8673        synchronized (this) {
8674            pkg = task.intent.getComponent().getPackageName();
8675        }
8676        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8677        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8678            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8679                    StatusBarManagerInternal.class);
8680            if (statusBarManager != null) {
8681                statusBarManager.showScreenPinningRequest();
8682            }
8683            return;
8684        }
8685        long ident = Binder.clearCallingIdentity();
8686        try {
8687            synchronized (this) {
8688                // Since we lost lock on task, make sure it is still there.
8689                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8690                if (task != null) {
8691                    if (!isSystemInitiated
8692                            && ((mStackSupervisor.getFocusedStack() == null)
8693                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8694                        throw new IllegalArgumentException("Invalid task, not in foreground");
8695                    }
8696                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8697                }
8698            }
8699        } finally {
8700            Binder.restoreCallingIdentity(ident);
8701        }
8702    }
8703
8704    @Override
8705    public void startLockTaskMode(int taskId) {
8706        final TaskRecord task;
8707        long ident = Binder.clearCallingIdentity();
8708        try {
8709            synchronized (this) {
8710                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8711            }
8712        } finally {
8713            Binder.restoreCallingIdentity(ident);
8714        }
8715        if (task != null) {
8716            startLockTaskMode(task);
8717        }
8718    }
8719
8720    @Override
8721    public void startLockTaskMode(IBinder token) {
8722        final TaskRecord task;
8723        long ident = Binder.clearCallingIdentity();
8724        try {
8725            synchronized (this) {
8726                final ActivityRecord r = ActivityRecord.forToken(token);
8727                if (r == null) {
8728                    return;
8729                }
8730                task = r.task;
8731            }
8732        } finally {
8733            Binder.restoreCallingIdentity(ident);
8734        }
8735        if (task != null) {
8736            startLockTaskMode(task);
8737        }
8738    }
8739
8740    @Override
8741    public void startLockTaskModeOnCurrent() throws RemoteException {
8742        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8743                "startLockTaskModeOnCurrent");
8744        long ident = Binder.clearCallingIdentity();
8745        try {
8746            ActivityRecord r = null;
8747            synchronized (this) {
8748                r = mStackSupervisor.topRunningActivityLocked();
8749            }
8750            startLockTaskMode(r.task);
8751        } finally {
8752            Binder.restoreCallingIdentity(ident);
8753        }
8754    }
8755
8756    @Override
8757    public void stopLockTaskMode() {
8758        // Verify that the user matches the package of the intent for the TaskRecord
8759        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8760        // and stopLockTaskMode.
8761        final int callingUid = Binder.getCallingUid();
8762        if (callingUid != Process.SYSTEM_UID) {
8763            try {
8764                String pkg =
8765                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8766                int uid = mContext.getPackageManager().getPackageUid(pkg,
8767                        Binder.getCallingUserHandle().getIdentifier());
8768                if (uid != callingUid) {
8769                    throw new SecurityException("Invalid uid, expected " + uid);
8770                }
8771            } catch (NameNotFoundException e) {
8772                Log.d(TAG, "stopLockTaskMode " + e);
8773                return;
8774            }
8775        }
8776        long ident = Binder.clearCallingIdentity();
8777        try {
8778            Log.d(TAG, "stopLockTaskMode");
8779            // Stop lock task
8780            synchronized (this) {
8781                mStackSupervisor.setLockTaskModeLocked(null, false);
8782            }
8783        } finally {
8784            Binder.restoreCallingIdentity(ident);
8785        }
8786    }
8787
8788    @Override
8789    public void stopLockTaskModeOnCurrent() throws RemoteException {
8790        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8791                "stopLockTaskModeOnCurrent");
8792        long ident = Binder.clearCallingIdentity();
8793        try {
8794            stopLockTaskMode();
8795        } finally {
8796            Binder.restoreCallingIdentity(ident);
8797        }
8798    }
8799
8800    @Override
8801    public boolean isInLockTaskMode() {
8802        synchronized (this) {
8803            return mStackSupervisor.isInLockTaskMode();
8804        }
8805    }
8806
8807    // =========================================================
8808    // CONTENT PROVIDERS
8809    // =========================================================
8810
8811    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8812        List<ProviderInfo> providers = null;
8813        try {
8814            providers = AppGlobals.getPackageManager().
8815                queryContentProviders(app.processName, app.uid,
8816                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8817        } catch (RemoteException ex) {
8818        }
8819        if (DEBUG_MU)
8820            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8821        int userId = app.userId;
8822        if (providers != null) {
8823            int N = providers.size();
8824            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8825            for (int i=0; i<N; i++) {
8826                ProviderInfo cpi =
8827                    (ProviderInfo)providers.get(i);
8828                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8829                        cpi.name, cpi.flags);
8830                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8831                    // This is a singleton provider, but a user besides the
8832                    // default user is asking to initialize a process it runs
8833                    // in...  well, no, it doesn't actually run in this process,
8834                    // it runs in the process of the default user.  Get rid of it.
8835                    providers.remove(i);
8836                    N--;
8837                    i--;
8838                    continue;
8839                }
8840
8841                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8842                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8843                if (cpr == null) {
8844                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8845                    mProviderMap.putProviderByClass(comp, cpr);
8846                }
8847                if (DEBUG_MU)
8848                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8849                app.pubProviders.put(cpi.name, cpr);
8850                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8851                    // Don't add this if it is a platform component that is marked
8852                    // to run in multiple processes, because this is actually
8853                    // part of the framework so doesn't make sense to track as a
8854                    // separate apk in the process.
8855                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8856                            mProcessStats);
8857                }
8858                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8859            }
8860        }
8861        return providers;
8862    }
8863
8864    /**
8865     * Check if {@link ProcessRecord} has a possible chance at accessing the
8866     * given {@link ProviderInfo}. Final permission checking is always done
8867     * in {@link ContentProvider}.
8868     */
8869    private final String checkContentProviderPermissionLocked(
8870            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8871        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8872        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8873        boolean checkedGrants = false;
8874        if (checkUser) {
8875            // Looking for cross-user grants before enforcing the typical cross-users permissions
8876            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8877            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8878                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8879                    return null;
8880                }
8881                checkedGrants = true;
8882            }
8883            userId = handleIncomingUser(callingPid, callingUid, userId,
8884                    false, ALLOW_NON_FULL,
8885                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8886            if (userId != tmpTargetUserId) {
8887                // When we actually went to determine the final targer user ID, this ended
8888                // up different than our initial check for the authority.  This is because
8889                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8890                // SELF.  So we need to re-check the grants again.
8891                checkedGrants = false;
8892            }
8893        }
8894        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8895                cpi.applicationInfo.uid, cpi.exported)
8896                == PackageManager.PERMISSION_GRANTED) {
8897            return null;
8898        }
8899        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8900                cpi.applicationInfo.uid, cpi.exported)
8901                == PackageManager.PERMISSION_GRANTED) {
8902            return null;
8903        }
8904
8905        PathPermission[] pps = cpi.pathPermissions;
8906        if (pps != null) {
8907            int i = pps.length;
8908            while (i > 0) {
8909                i--;
8910                PathPermission pp = pps[i];
8911                String pprperm = pp.getReadPermission();
8912                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8913                        cpi.applicationInfo.uid, cpi.exported)
8914                        == PackageManager.PERMISSION_GRANTED) {
8915                    return null;
8916                }
8917                String ppwperm = pp.getWritePermission();
8918                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8919                        cpi.applicationInfo.uid, cpi.exported)
8920                        == PackageManager.PERMISSION_GRANTED) {
8921                    return null;
8922                }
8923            }
8924        }
8925        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8926            return null;
8927        }
8928
8929        String msg;
8930        if (!cpi.exported) {
8931            msg = "Permission Denial: opening provider " + cpi.name
8932                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8933                    + ", uid=" + callingUid + ") that is not exported from uid "
8934                    + cpi.applicationInfo.uid;
8935        } else {
8936            msg = "Permission Denial: opening provider " + cpi.name
8937                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8938                    + ", uid=" + callingUid + ") requires "
8939                    + cpi.readPermission + " or " + cpi.writePermission;
8940        }
8941        Slog.w(TAG, msg);
8942        return msg;
8943    }
8944
8945    /**
8946     * Returns if the ContentProvider has granted a uri to callingUid
8947     */
8948    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8949        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8950        if (perms != null) {
8951            for (int i=perms.size()-1; i>=0; i--) {
8952                GrantUri grantUri = perms.keyAt(i);
8953                if (grantUri.sourceUserId == userId || !checkUser) {
8954                    if (matchesProvider(grantUri.uri, cpi)) {
8955                        return true;
8956                    }
8957                }
8958            }
8959        }
8960        return false;
8961    }
8962
8963    /**
8964     * Returns true if the uri authority is one of the authorities specified in the provider.
8965     */
8966    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8967        String uriAuth = uri.getAuthority();
8968        String cpiAuth = cpi.authority;
8969        if (cpiAuth.indexOf(';') == -1) {
8970            return cpiAuth.equals(uriAuth);
8971        }
8972        String[] cpiAuths = cpiAuth.split(";");
8973        int length = cpiAuths.length;
8974        for (int i = 0; i < length; i++) {
8975            if (cpiAuths[i].equals(uriAuth)) return true;
8976        }
8977        return false;
8978    }
8979
8980    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8981            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8982        if (r != null) {
8983            for (int i=0; i<r.conProviders.size(); i++) {
8984                ContentProviderConnection conn = r.conProviders.get(i);
8985                if (conn.provider == cpr) {
8986                    if (DEBUG_PROVIDER) Slog.v(TAG,
8987                            "Adding provider requested by "
8988                            + r.processName + " from process "
8989                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8990                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8991                    if (stable) {
8992                        conn.stableCount++;
8993                        conn.numStableIncs++;
8994                    } else {
8995                        conn.unstableCount++;
8996                        conn.numUnstableIncs++;
8997                    }
8998                    return conn;
8999                }
9000            }
9001            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9002            if (stable) {
9003                conn.stableCount = 1;
9004                conn.numStableIncs = 1;
9005            } else {
9006                conn.unstableCount = 1;
9007                conn.numUnstableIncs = 1;
9008            }
9009            cpr.connections.add(conn);
9010            r.conProviders.add(conn);
9011            return conn;
9012        }
9013        cpr.addExternalProcessHandleLocked(externalProcessToken);
9014        return null;
9015    }
9016
9017    boolean decProviderCountLocked(ContentProviderConnection conn,
9018            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9019        if (conn != null) {
9020            cpr = conn.provider;
9021            if (DEBUG_PROVIDER) Slog.v(TAG,
9022                    "Removing provider requested by "
9023                    + conn.client.processName + " from process "
9024                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9025                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9026            if (stable) {
9027                conn.stableCount--;
9028            } else {
9029                conn.unstableCount--;
9030            }
9031            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9032                cpr.connections.remove(conn);
9033                conn.client.conProviders.remove(conn);
9034                return true;
9035            }
9036            return false;
9037        }
9038        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9039        return false;
9040    }
9041
9042    private void checkTime(long startTime, String where) {
9043        long now = SystemClock.elapsedRealtime();
9044        if ((now-startTime) > 1000) {
9045            // If we are taking more than a second, log about it.
9046            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9047        }
9048    }
9049
9050    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9051            String name, IBinder token, boolean stable, int userId) {
9052        ContentProviderRecord cpr;
9053        ContentProviderConnection conn = null;
9054        ProviderInfo cpi = null;
9055
9056        synchronized(this) {
9057            long startTime = SystemClock.elapsedRealtime();
9058
9059            ProcessRecord r = null;
9060            if (caller != null) {
9061                r = getRecordForAppLocked(caller);
9062                if (r == null) {
9063                    throw new SecurityException(
9064                            "Unable to find app for caller " + caller
9065                          + " (pid=" + Binder.getCallingPid()
9066                          + ") when getting content provider " + name);
9067                }
9068            }
9069
9070            boolean checkCrossUser = true;
9071
9072            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9073
9074            // First check if this content provider has been published...
9075            cpr = mProviderMap.getProviderByName(name, userId);
9076            // If that didn't work, check if it exists for user 0 and then
9077            // verify that it's a singleton provider before using it.
9078            if (cpr == null && userId != UserHandle.USER_OWNER) {
9079                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9080                if (cpr != null) {
9081                    cpi = cpr.info;
9082                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9083                            cpi.name, cpi.flags)
9084                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9085                        userId = UserHandle.USER_OWNER;
9086                        checkCrossUser = false;
9087                    } else {
9088                        cpr = null;
9089                        cpi = null;
9090                    }
9091                }
9092            }
9093
9094            boolean providerRunning = cpr != null;
9095            if (providerRunning) {
9096                cpi = cpr.info;
9097                String msg;
9098                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9099                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9100                        != null) {
9101                    throw new SecurityException(msg);
9102                }
9103                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9104
9105                if (r != null && cpr.canRunHere(r)) {
9106                    // This provider has been published or is in the process
9107                    // of being published...  but it is also allowed to run
9108                    // in the caller's process, so don't make a connection
9109                    // and just let the caller instantiate its own instance.
9110                    ContentProviderHolder holder = cpr.newHolder(null);
9111                    // don't give caller the provider object, it needs
9112                    // to make its own.
9113                    holder.provider = null;
9114                    return holder;
9115                }
9116
9117                final long origId = Binder.clearCallingIdentity();
9118
9119                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9120
9121                // In this case the provider instance already exists, so we can
9122                // return it right away.
9123                conn = incProviderCountLocked(r, cpr, token, stable);
9124                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9125                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9126                        // If this is a perceptible app accessing the provider,
9127                        // make sure to count it as being accessed and thus
9128                        // back up on the LRU list.  This is good because
9129                        // content providers are often expensive to start.
9130                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9131                        updateLruProcessLocked(cpr.proc, false, null);
9132                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9133                    }
9134                }
9135
9136                if (cpr.proc != null) {
9137                    if (false) {
9138                        if (cpr.name.flattenToShortString().equals(
9139                                "com.android.providers.calendar/.CalendarProvider2")) {
9140                            Slog.v(TAG, "****************** KILLING "
9141                                + cpr.name.flattenToShortString());
9142                            Process.killProcess(cpr.proc.pid);
9143                        }
9144                    }
9145                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9146                    boolean success = updateOomAdjLocked(cpr.proc);
9147                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9148                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9149                    // NOTE: there is still a race here where a signal could be
9150                    // pending on the process even though we managed to update its
9151                    // adj level.  Not sure what to do about this, but at least
9152                    // the race is now smaller.
9153                    if (!success) {
9154                        // Uh oh...  it looks like the provider's process
9155                        // has been killed on us.  We need to wait for a new
9156                        // process to be started, and make sure its death
9157                        // doesn't kill our process.
9158                        Slog.i(TAG,
9159                                "Existing provider " + cpr.name.flattenToShortString()
9160                                + " is crashing; detaching " + r);
9161                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9162                        checkTime(startTime, "getContentProviderImpl: before appDied");
9163                        appDiedLocked(cpr.proc);
9164                        checkTime(startTime, "getContentProviderImpl: after appDied");
9165                        if (!lastRef) {
9166                            // This wasn't the last ref our process had on
9167                            // the provider...  we have now been killed, bail.
9168                            return null;
9169                        }
9170                        providerRunning = false;
9171                        conn = null;
9172                    }
9173                }
9174
9175                Binder.restoreCallingIdentity(origId);
9176            }
9177
9178            boolean singleton;
9179            if (!providerRunning) {
9180                try {
9181                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9182                    cpi = AppGlobals.getPackageManager().
9183                        resolveContentProvider(name,
9184                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9185                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9186                } catch (RemoteException ex) {
9187                }
9188                if (cpi == null) {
9189                    return null;
9190                }
9191                // If the provider is a singleton AND
9192                // (it's a call within the same user || the provider is a
9193                // privileged app)
9194                // Then allow connecting to the singleton provider
9195                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9196                        cpi.name, cpi.flags)
9197                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9198                if (singleton) {
9199                    userId = UserHandle.USER_OWNER;
9200                }
9201                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9202                checkTime(startTime, "getContentProviderImpl: got app info for user");
9203
9204                String msg;
9205                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9206                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9207                        != null) {
9208                    throw new SecurityException(msg);
9209                }
9210                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9211
9212                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9213                        && !cpi.processName.equals("system")) {
9214                    // If this content provider does not run in the system
9215                    // process, and the system is not yet ready to run other
9216                    // processes, then fail fast instead of hanging.
9217                    throw new IllegalArgumentException(
9218                            "Attempt to launch content provider before system ready");
9219                }
9220
9221                // Make sure that the user who owns this provider is started.  If not,
9222                // we don't want to allow it to run.
9223                if (mStartedUsers.get(userId) == null) {
9224                    Slog.w(TAG, "Unable to launch app "
9225                            + cpi.applicationInfo.packageName + "/"
9226                            + cpi.applicationInfo.uid + " for provider "
9227                            + name + ": user " + userId + " is stopped");
9228                    return null;
9229                }
9230
9231                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9232                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9233                cpr = mProviderMap.getProviderByClass(comp, userId);
9234                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9235                final boolean firstClass = cpr == null;
9236                if (firstClass) {
9237                    final long ident = Binder.clearCallingIdentity();
9238                    try {
9239                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9240                        ApplicationInfo ai =
9241                            AppGlobals.getPackageManager().
9242                                getApplicationInfo(
9243                                        cpi.applicationInfo.packageName,
9244                                        STOCK_PM_FLAGS, userId);
9245                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9246                        if (ai == null) {
9247                            Slog.w(TAG, "No package info for content provider "
9248                                    + cpi.name);
9249                            return null;
9250                        }
9251                        ai = getAppInfoForUser(ai, userId);
9252                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9253                    } catch (RemoteException ex) {
9254                        // pm is in same process, this will never happen.
9255                    } finally {
9256                        Binder.restoreCallingIdentity(ident);
9257                    }
9258                }
9259
9260                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9261
9262                if (r != null && cpr.canRunHere(r)) {
9263                    // If this is a multiprocess provider, then just return its
9264                    // info and allow the caller to instantiate it.  Only do
9265                    // this if the provider is the same user as the caller's
9266                    // process, or can run as root (so can be in any process).
9267                    return cpr.newHolder(null);
9268                }
9269
9270                if (DEBUG_PROVIDER) {
9271                    RuntimeException e = new RuntimeException("here");
9272                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9273                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9274                }
9275
9276                // This is single process, and our app is now connecting to it.
9277                // See if we are already in the process of launching this
9278                // provider.
9279                final int N = mLaunchingProviders.size();
9280                int i;
9281                for (i=0; i<N; i++) {
9282                    if (mLaunchingProviders.get(i) == cpr) {
9283                        break;
9284                    }
9285                }
9286
9287                // If the provider is not already being launched, then get it
9288                // started.
9289                if (i >= N) {
9290                    final long origId = Binder.clearCallingIdentity();
9291
9292                    try {
9293                        // Content provider is now in use, its package can't be stopped.
9294                        try {
9295                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9296                            AppGlobals.getPackageManager().setPackageStoppedState(
9297                                    cpr.appInfo.packageName, false, userId);
9298                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9299                        } catch (RemoteException e) {
9300                        } catch (IllegalArgumentException e) {
9301                            Slog.w(TAG, "Failed trying to unstop package "
9302                                    + cpr.appInfo.packageName + ": " + e);
9303                        }
9304
9305                        // Use existing process if already started
9306                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9307                        ProcessRecord proc = getProcessRecordLocked(
9308                                cpi.processName, cpr.appInfo.uid, false);
9309                        if (proc != null && proc.thread != null) {
9310                            if (DEBUG_PROVIDER) {
9311                                Slog.d(TAG, "Installing in existing process " + proc);
9312                            }
9313                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9314                            proc.pubProviders.put(cpi.name, cpr);
9315                            try {
9316                                proc.thread.scheduleInstallProvider(cpi);
9317                            } catch (RemoteException e) {
9318                            }
9319                        } else {
9320                            checkTime(startTime, "getContentProviderImpl: before start process");
9321                            proc = startProcessLocked(cpi.processName,
9322                                    cpr.appInfo, false, 0, "content provider",
9323                                    new ComponentName(cpi.applicationInfo.packageName,
9324                                            cpi.name), false, false, false);
9325                            checkTime(startTime, "getContentProviderImpl: after start process");
9326                            if (proc == null) {
9327                                Slog.w(TAG, "Unable to launch app "
9328                                        + cpi.applicationInfo.packageName + "/"
9329                                        + cpi.applicationInfo.uid + " for provider "
9330                                        + name + ": process is bad");
9331                                return null;
9332                            }
9333                        }
9334                        cpr.launchingApp = proc;
9335                        mLaunchingProviders.add(cpr);
9336                    } finally {
9337                        Binder.restoreCallingIdentity(origId);
9338                    }
9339                }
9340
9341                checkTime(startTime, "getContentProviderImpl: updating data structures");
9342
9343                // Make sure the provider is published (the same provider class
9344                // may be published under multiple names).
9345                if (firstClass) {
9346                    mProviderMap.putProviderByClass(comp, cpr);
9347                }
9348
9349                mProviderMap.putProviderByName(name, cpr);
9350                conn = incProviderCountLocked(r, cpr, token, stable);
9351                if (conn != null) {
9352                    conn.waiting = true;
9353                }
9354            }
9355            checkTime(startTime, "getContentProviderImpl: done!");
9356        }
9357
9358        // Wait for the provider to be published...
9359        synchronized (cpr) {
9360            while (cpr.provider == null) {
9361                if (cpr.launchingApp == null) {
9362                    Slog.w(TAG, "Unable to launch app "
9363                            + cpi.applicationInfo.packageName + "/"
9364                            + cpi.applicationInfo.uid + " for provider "
9365                            + name + ": launching app became null");
9366                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9367                            UserHandle.getUserId(cpi.applicationInfo.uid),
9368                            cpi.applicationInfo.packageName,
9369                            cpi.applicationInfo.uid, name);
9370                    return null;
9371                }
9372                try {
9373                    if (DEBUG_MU) {
9374                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9375                                + cpr.launchingApp);
9376                    }
9377                    if (conn != null) {
9378                        conn.waiting = true;
9379                    }
9380                    cpr.wait();
9381                } catch (InterruptedException ex) {
9382                } finally {
9383                    if (conn != null) {
9384                        conn.waiting = false;
9385                    }
9386                }
9387            }
9388        }
9389        return cpr != null ? cpr.newHolder(conn) : null;
9390    }
9391
9392    @Override
9393    public final ContentProviderHolder getContentProvider(
9394            IApplicationThread caller, String name, int userId, boolean stable) {
9395        enforceNotIsolatedCaller("getContentProvider");
9396        if (caller == null) {
9397            String msg = "null IApplicationThread when getting content provider "
9398                    + name;
9399            Slog.w(TAG, msg);
9400            throw new SecurityException(msg);
9401        }
9402        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9403        // with cross-user grant.
9404        return getContentProviderImpl(caller, name, null, stable, userId);
9405    }
9406
9407    public ContentProviderHolder getContentProviderExternal(
9408            String name, int userId, IBinder token) {
9409        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9410            "Do not have permission in call getContentProviderExternal()");
9411        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9412                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9413        return getContentProviderExternalUnchecked(name, token, userId);
9414    }
9415
9416    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9417            IBinder token, int userId) {
9418        return getContentProviderImpl(null, name, token, true, userId);
9419    }
9420
9421    /**
9422     * Drop a content provider from a ProcessRecord's bookkeeping
9423     */
9424    public void removeContentProvider(IBinder connection, boolean stable) {
9425        enforceNotIsolatedCaller("removeContentProvider");
9426        long ident = Binder.clearCallingIdentity();
9427        try {
9428            synchronized (this) {
9429                ContentProviderConnection conn;
9430                try {
9431                    conn = (ContentProviderConnection)connection;
9432                } catch (ClassCastException e) {
9433                    String msg ="removeContentProvider: " + connection
9434                            + " not a ContentProviderConnection";
9435                    Slog.w(TAG, msg);
9436                    throw new IllegalArgumentException(msg);
9437                }
9438                if (conn == null) {
9439                    throw new NullPointerException("connection is null");
9440                }
9441                if (decProviderCountLocked(conn, null, null, stable)) {
9442                    updateOomAdjLocked();
9443                }
9444            }
9445        } finally {
9446            Binder.restoreCallingIdentity(ident);
9447        }
9448    }
9449
9450    public void removeContentProviderExternal(String name, IBinder token) {
9451        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9452            "Do not have permission in call removeContentProviderExternal()");
9453        int userId = UserHandle.getCallingUserId();
9454        long ident = Binder.clearCallingIdentity();
9455        try {
9456            removeContentProviderExternalUnchecked(name, token, userId);
9457        } finally {
9458            Binder.restoreCallingIdentity(ident);
9459        }
9460    }
9461
9462    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9463        synchronized (this) {
9464            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9465            if(cpr == null) {
9466                //remove from mProvidersByClass
9467                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9468                return;
9469            }
9470
9471            //update content provider record entry info
9472            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9473            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9474            if (localCpr.hasExternalProcessHandles()) {
9475                if (localCpr.removeExternalProcessHandleLocked(token)) {
9476                    updateOomAdjLocked();
9477                } else {
9478                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9479                            + " with no external reference for token: "
9480                            + token + ".");
9481                }
9482            } else {
9483                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9484                        + " with no external references.");
9485            }
9486        }
9487    }
9488
9489    public final void publishContentProviders(IApplicationThread caller,
9490            List<ContentProviderHolder> providers) {
9491        if (providers == null) {
9492            return;
9493        }
9494
9495        enforceNotIsolatedCaller("publishContentProviders");
9496        synchronized (this) {
9497            final ProcessRecord r = getRecordForAppLocked(caller);
9498            if (DEBUG_MU)
9499                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9500            if (r == null) {
9501                throw new SecurityException(
9502                        "Unable to find app for caller " + caller
9503                      + " (pid=" + Binder.getCallingPid()
9504                      + ") when publishing content providers");
9505            }
9506
9507            final long origId = Binder.clearCallingIdentity();
9508
9509            final int N = providers.size();
9510            for (int i=0; i<N; i++) {
9511                ContentProviderHolder src = providers.get(i);
9512                if (src == null || src.info == null || src.provider == null) {
9513                    continue;
9514                }
9515                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9516                if (DEBUG_MU)
9517                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9518                if (dst != null) {
9519                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9520                    mProviderMap.putProviderByClass(comp, dst);
9521                    String names[] = dst.info.authority.split(";");
9522                    for (int j = 0; j < names.length; j++) {
9523                        mProviderMap.putProviderByName(names[j], dst);
9524                    }
9525
9526                    int NL = mLaunchingProviders.size();
9527                    int j;
9528                    for (j=0; j<NL; j++) {
9529                        if (mLaunchingProviders.get(j) == dst) {
9530                            mLaunchingProviders.remove(j);
9531                            j--;
9532                            NL--;
9533                        }
9534                    }
9535                    synchronized (dst) {
9536                        dst.provider = src.provider;
9537                        dst.proc = r;
9538                        dst.notifyAll();
9539                    }
9540                    updateOomAdjLocked(r);
9541                }
9542            }
9543
9544            Binder.restoreCallingIdentity(origId);
9545        }
9546    }
9547
9548    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9549        ContentProviderConnection conn;
9550        try {
9551            conn = (ContentProviderConnection)connection;
9552        } catch (ClassCastException e) {
9553            String msg ="refContentProvider: " + connection
9554                    + " not a ContentProviderConnection";
9555            Slog.w(TAG, msg);
9556            throw new IllegalArgumentException(msg);
9557        }
9558        if (conn == null) {
9559            throw new NullPointerException("connection is null");
9560        }
9561
9562        synchronized (this) {
9563            if (stable > 0) {
9564                conn.numStableIncs += stable;
9565            }
9566            stable = conn.stableCount + stable;
9567            if (stable < 0) {
9568                throw new IllegalStateException("stableCount < 0: " + stable);
9569            }
9570
9571            if (unstable > 0) {
9572                conn.numUnstableIncs += unstable;
9573            }
9574            unstable = conn.unstableCount + unstable;
9575            if (unstable < 0) {
9576                throw new IllegalStateException("unstableCount < 0: " + unstable);
9577            }
9578
9579            if ((stable+unstable) <= 0) {
9580                throw new IllegalStateException("ref counts can't go to zero here: stable="
9581                        + stable + " unstable=" + unstable);
9582            }
9583            conn.stableCount = stable;
9584            conn.unstableCount = unstable;
9585            return !conn.dead;
9586        }
9587    }
9588
9589    public void unstableProviderDied(IBinder connection) {
9590        ContentProviderConnection conn;
9591        try {
9592            conn = (ContentProviderConnection)connection;
9593        } catch (ClassCastException e) {
9594            String msg ="refContentProvider: " + connection
9595                    + " not a ContentProviderConnection";
9596            Slog.w(TAG, msg);
9597            throw new IllegalArgumentException(msg);
9598        }
9599        if (conn == null) {
9600            throw new NullPointerException("connection is null");
9601        }
9602
9603        // Safely retrieve the content provider associated with the connection.
9604        IContentProvider provider;
9605        synchronized (this) {
9606            provider = conn.provider.provider;
9607        }
9608
9609        if (provider == null) {
9610            // Um, yeah, we're way ahead of you.
9611            return;
9612        }
9613
9614        // Make sure the caller is being honest with us.
9615        if (provider.asBinder().pingBinder()) {
9616            // Er, no, still looks good to us.
9617            synchronized (this) {
9618                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9619                        + " says " + conn + " died, but we don't agree");
9620                return;
9621            }
9622        }
9623
9624        // Well look at that!  It's dead!
9625        synchronized (this) {
9626            if (conn.provider.provider != provider) {
9627                // But something changed...  good enough.
9628                return;
9629            }
9630
9631            ProcessRecord proc = conn.provider.proc;
9632            if (proc == null || proc.thread == null) {
9633                // Seems like the process is already cleaned up.
9634                return;
9635            }
9636
9637            // As far as we're concerned, this is just like receiving a
9638            // death notification...  just a bit prematurely.
9639            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9640                    + ") early provider death");
9641            final long ident = Binder.clearCallingIdentity();
9642            try {
9643                appDiedLocked(proc);
9644            } finally {
9645                Binder.restoreCallingIdentity(ident);
9646            }
9647        }
9648    }
9649
9650    @Override
9651    public void appNotRespondingViaProvider(IBinder connection) {
9652        enforceCallingPermission(
9653                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9654
9655        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9656        if (conn == null) {
9657            Slog.w(TAG, "ContentProviderConnection is null");
9658            return;
9659        }
9660
9661        final ProcessRecord host = conn.provider.proc;
9662        if (host == null) {
9663            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9664            return;
9665        }
9666
9667        final long token = Binder.clearCallingIdentity();
9668        try {
9669            appNotResponding(host, null, null, false, "ContentProvider not responding");
9670        } finally {
9671            Binder.restoreCallingIdentity(token);
9672        }
9673    }
9674
9675    public final void installSystemProviders() {
9676        List<ProviderInfo> providers;
9677        synchronized (this) {
9678            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9679            providers = generateApplicationProvidersLocked(app);
9680            if (providers != null) {
9681                for (int i=providers.size()-1; i>=0; i--) {
9682                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9683                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9684                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9685                                + ": not system .apk");
9686                        providers.remove(i);
9687                    }
9688                }
9689            }
9690        }
9691        if (providers != null) {
9692            mSystemThread.installSystemProviders(providers);
9693        }
9694
9695        mCoreSettingsObserver = new CoreSettingsObserver(this);
9696
9697        //mUsageStatsService.monitorPackages();
9698    }
9699
9700    /**
9701     * Allows apps to retrieve the MIME type of a URI.
9702     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9703     * users, then it does not need permission to access the ContentProvider.
9704     * Either, it needs cross-user uri grants.
9705     *
9706     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9707     *
9708     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9709     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9710     */
9711    public String getProviderMimeType(Uri uri, int userId) {
9712        enforceNotIsolatedCaller("getProviderMimeType");
9713        final String name = uri.getAuthority();
9714        int callingUid = Binder.getCallingUid();
9715        int callingPid = Binder.getCallingPid();
9716        long ident = 0;
9717        boolean clearedIdentity = false;
9718        userId = unsafeConvertIncomingUser(userId);
9719        if (canClearIdentity(callingPid, callingUid, userId)) {
9720            clearedIdentity = true;
9721            ident = Binder.clearCallingIdentity();
9722        }
9723        ContentProviderHolder holder = null;
9724        try {
9725            holder = getContentProviderExternalUnchecked(name, null, userId);
9726            if (holder != null) {
9727                return holder.provider.getType(uri);
9728            }
9729        } catch (RemoteException e) {
9730            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9731            return null;
9732        } finally {
9733            // We need to clear the identity to call removeContentProviderExternalUnchecked
9734            if (!clearedIdentity) {
9735                ident = Binder.clearCallingIdentity();
9736            }
9737            try {
9738                if (holder != null) {
9739                    removeContentProviderExternalUnchecked(name, null, userId);
9740                }
9741            } finally {
9742                Binder.restoreCallingIdentity(ident);
9743            }
9744        }
9745
9746        return null;
9747    }
9748
9749    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9750        if (UserHandle.getUserId(callingUid) == userId) {
9751            return true;
9752        }
9753        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9754                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9755                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9756                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9757                return true;
9758        }
9759        return false;
9760    }
9761
9762    // =========================================================
9763    // GLOBAL MANAGEMENT
9764    // =========================================================
9765
9766    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9767            boolean isolated, int isolatedUid) {
9768        String proc = customProcess != null ? customProcess : info.processName;
9769        BatteryStatsImpl.Uid.Proc ps = null;
9770        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9771        int uid = info.uid;
9772        if (isolated) {
9773            if (isolatedUid == 0) {
9774                int userId = UserHandle.getUserId(uid);
9775                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9776                while (true) {
9777                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9778                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9779                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9780                    }
9781                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9782                    mNextIsolatedProcessUid++;
9783                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9784                        // No process for this uid, use it.
9785                        break;
9786                    }
9787                    stepsLeft--;
9788                    if (stepsLeft <= 0) {
9789                        return null;
9790                    }
9791                }
9792            } else {
9793                // Special case for startIsolatedProcess (internal only), where
9794                // the uid of the isolated process is specified by the caller.
9795                uid = isolatedUid;
9796            }
9797        }
9798        return new ProcessRecord(stats, info, proc, uid);
9799    }
9800
9801    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9802            String abiOverride) {
9803        ProcessRecord app;
9804        if (!isolated) {
9805            app = getProcessRecordLocked(info.processName, info.uid, true);
9806        } else {
9807            app = null;
9808        }
9809
9810        if (app == null) {
9811            app = newProcessRecordLocked(info, null, isolated, 0);
9812            mProcessNames.put(info.processName, app.uid, app);
9813            if (isolated) {
9814                mIsolatedProcesses.put(app.uid, app);
9815            }
9816            updateLruProcessLocked(app, false, null);
9817            updateOomAdjLocked();
9818        }
9819
9820        // This package really, really can not be stopped.
9821        try {
9822            AppGlobals.getPackageManager().setPackageStoppedState(
9823                    info.packageName, false, UserHandle.getUserId(app.uid));
9824        } catch (RemoteException e) {
9825        } catch (IllegalArgumentException e) {
9826            Slog.w(TAG, "Failed trying to unstop package "
9827                    + info.packageName + ": " + e);
9828        }
9829
9830        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9831                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9832            app.persistent = true;
9833            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9834        }
9835        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9836            mPersistentStartingProcesses.add(app);
9837            startProcessLocked(app, "added application", app.processName, abiOverride,
9838                    null /* entryPoint */, null /* entryPointArgs */);
9839        }
9840
9841        return app;
9842    }
9843
9844    public void unhandledBack() {
9845        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9846                "unhandledBack()");
9847
9848        synchronized(this) {
9849            final long origId = Binder.clearCallingIdentity();
9850            try {
9851                getFocusedStack().unhandledBackLocked();
9852            } finally {
9853                Binder.restoreCallingIdentity(origId);
9854            }
9855        }
9856    }
9857
9858    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9859        enforceNotIsolatedCaller("openContentUri");
9860        final int userId = UserHandle.getCallingUserId();
9861        String name = uri.getAuthority();
9862        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9863        ParcelFileDescriptor pfd = null;
9864        if (cph != null) {
9865            // We record the binder invoker's uid in thread-local storage before
9866            // going to the content provider to open the file.  Later, in the code
9867            // that handles all permissions checks, we look for this uid and use
9868            // that rather than the Activity Manager's own uid.  The effect is that
9869            // we do the check against the caller's permissions even though it looks
9870            // to the content provider like the Activity Manager itself is making
9871            // the request.
9872            sCallerIdentity.set(new Identity(
9873                    Binder.getCallingPid(), Binder.getCallingUid()));
9874            try {
9875                pfd = cph.provider.openFile(null, uri, "r", null);
9876            } catch (FileNotFoundException e) {
9877                // do nothing; pfd will be returned null
9878            } finally {
9879                // Ensure that whatever happens, we clean up the identity state
9880                sCallerIdentity.remove();
9881            }
9882
9883            // We've got the fd now, so we're done with the provider.
9884            removeContentProviderExternalUnchecked(name, null, userId);
9885        } else {
9886            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9887        }
9888        return pfd;
9889    }
9890
9891    // Actually is sleeping or shutting down or whatever else in the future
9892    // is an inactive state.
9893    public boolean isSleepingOrShuttingDown() {
9894        return isSleeping() || mShuttingDown;
9895    }
9896
9897    public boolean isSleeping() {
9898        return mSleeping;
9899    }
9900
9901    void goingToSleep() {
9902        synchronized(this) {
9903            mWentToSleep = true;
9904            goToSleepIfNeededLocked();
9905        }
9906    }
9907
9908    void finishRunningVoiceLocked() {
9909        if (mRunningVoice) {
9910            mRunningVoice = false;
9911            goToSleepIfNeededLocked();
9912        }
9913    }
9914
9915    void goToSleepIfNeededLocked() {
9916        if (mWentToSleep && !mRunningVoice) {
9917            if (!mSleeping) {
9918                mSleeping = true;
9919                mStackSupervisor.goingToSleepLocked();
9920
9921                // Initialize the wake times of all processes.
9922                checkExcessivePowerUsageLocked(false);
9923                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9924                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9925                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9926            }
9927        }
9928    }
9929
9930    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9931        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9932            // Never persist the home stack.
9933            return;
9934        }
9935        mTaskPersister.wakeup(task, flush);
9936    }
9937
9938    @Override
9939    public boolean shutdown(int timeout) {
9940        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9941                != PackageManager.PERMISSION_GRANTED) {
9942            throw new SecurityException("Requires permission "
9943                    + android.Manifest.permission.SHUTDOWN);
9944        }
9945
9946        boolean timedout = false;
9947
9948        synchronized(this) {
9949            mShuttingDown = true;
9950            updateEventDispatchingLocked();
9951            timedout = mStackSupervisor.shutdownLocked(timeout);
9952        }
9953
9954        mAppOpsService.shutdown();
9955        if (mUsageStatsService != null) {
9956            mUsageStatsService.prepareShutdown();
9957        }
9958        mBatteryStatsService.shutdown();
9959        synchronized (this) {
9960            mProcessStats.shutdownLocked();
9961        }
9962        notifyTaskPersisterLocked(null, true);
9963
9964        return timedout;
9965    }
9966
9967    public final void activitySlept(IBinder token) {
9968        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9969
9970        final long origId = Binder.clearCallingIdentity();
9971
9972        synchronized (this) {
9973            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9974            if (r != null) {
9975                mStackSupervisor.activitySleptLocked(r);
9976            }
9977        }
9978
9979        Binder.restoreCallingIdentity(origId);
9980    }
9981
9982    private String lockScreenShownToString() {
9983        switch (mLockScreenShown) {
9984            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
9985            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
9986            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
9987            default: return "Unknown=" + mLockScreenShown;
9988        }
9989    }
9990
9991    void logLockScreen(String msg) {
9992        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9993                " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" +
9994                mWentToSleep + " mSleeping=" + mSleeping);
9995    }
9996
9997    void comeOutOfSleepIfNeededLocked() {
9998        if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) {
9999            if (mSleeping) {
10000                mSleeping = false;
10001                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10002            }
10003        }
10004    }
10005
10006    void wakingUp() {
10007        synchronized(this) {
10008            mWentToSleep = false;
10009            comeOutOfSleepIfNeededLocked();
10010        }
10011    }
10012
10013    void startRunningVoiceLocked() {
10014        if (!mRunningVoice) {
10015            mRunningVoice = true;
10016            comeOutOfSleepIfNeededLocked();
10017        }
10018    }
10019
10020    private void updateEventDispatchingLocked() {
10021        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10022    }
10023
10024    public void setLockScreenShown(boolean shown) {
10025        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10026                != PackageManager.PERMISSION_GRANTED) {
10027            throw new SecurityException("Requires permission "
10028                    + android.Manifest.permission.DEVICE_POWER);
10029        }
10030
10031        synchronized(this) {
10032            long ident = Binder.clearCallingIdentity();
10033            try {
10034                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10035                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10036                comeOutOfSleepIfNeededLocked();
10037            } finally {
10038                Binder.restoreCallingIdentity(ident);
10039            }
10040        }
10041    }
10042
10043    @Override
10044    public void stopAppSwitches() {
10045        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10046                != PackageManager.PERMISSION_GRANTED) {
10047            throw new SecurityException("Requires permission "
10048                    + android.Manifest.permission.STOP_APP_SWITCHES);
10049        }
10050
10051        synchronized(this) {
10052            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10053                    + APP_SWITCH_DELAY_TIME;
10054            mDidAppSwitch = false;
10055            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10056            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10057            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10058        }
10059    }
10060
10061    public void resumeAppSwitches() {
10062        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10063                != PackageManager.PERMISSION_GRANTED) {
10064            throw new SecurityException("Requires permission "
10065                    + android.Manifest.permission.STOP_APP_SWITCHES);
10066        }
10067
10068        synchronized(this) {
10069            // Note that we don't execute any pending app switches... we will
10070            // let those wait until either the timeout, or the next start
10071            // activity request.
10072            mAppSwitchesAllowedTime = 0;
10073        }
10074    }
10075
10076    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10077            int callingPid, int callingUid, String name) {
10078        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10079            return true;
10080        }
10081
10082        int perm = checkComponentPermission(
10083                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10084                sourceUid, -1, true);
10085        if (perm == PackageManager.PERMISSION_GRANTED) {
10086            return true;
10087        }
10088
10089        // If the actual IPC caller is different from the logical source, then
10090        // also see if they are allowed to control app switches.
10091        if (callingUid != -1 && callingUid != sourceUid) {
10092            perm = checkComponentPermission(
10093                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10094                    callingUid, -1, true);
10095            if (perm == PackageManager.PERMISSION_GRANTED) {
10096                return true;
10097            }
10098        }
10099
10100        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10101        return false;
10102    }
10103
10104    public void setDebugApp(String packageName, boolean waitForDebugger,
10105            boolean persistent) {
10106        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10107                "setDebugApp()");
10108
10109        long ident = Binder.clearCallingIdentity();
10110        try {
10111            // Note that this is not really thread safe if there are multiple
10112            // callers into it at the same time, but that's not a situation we
10113            // care about.
10114            if (persistent) {
10115                final ContentResolver resolver = mContext.getContentResolver();
10116                Settings.Global.putString(
10117                    resolver, Settings.Global.DEBUG_APP,
10118                    packageName);
10119                Settings.Global.putInt(
10120                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10121                    waitForDebugger ? 1 : 0);
10122            }
10123
10124            synchronized (this) {
10125                if (!persistent) {
10126                    mOrigDebugApp = mDebugApp;
10127                    mOrigWaitForDebugger = mWaitForDebugger;
10128                }
10129                mDebugApp = packageName;
10130                mWaitForDebugger = waitForDebugger;
10131                mDebugTransient = !persistent;
10132                if (packageName != null) {
10133                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10134                            false, UserHandle.USER_ALL, "set debug app");
10135                }
10136            }
10137        } finally {
10138            Binder.restoreCallingIdentity(ident);
10139        }
10140    }
10141
10142    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10143        synchronized (this) {
10144            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10145            if (!isDebuggable) {
10146                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10147                    throw new SecurityException("Process not debuggable: " + app.packageName);
10148                }
10149            }
10150
10151            mOpenGlTraceApp = processName;
10152        }
10153    }
10154
10155    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10156        synchronized (this) {
10157            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10158            if (!isDebuggable) {
10159                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10160                    throw new SecurityException("Process not debuggable: " + app.packageName);
10161                }
10162            }
10163            mProfileApp = processName;
10164            mProfileFile = profilerInfo.profileFile;
10165            if (mProfileFd != null) {
10166                try {
10167                    mProfileFd.close();
10168                } catch (IOException e) {
10169                }
10170                mProfileFd = null;
10171            }
10172            mProfileFd = profilerInfo.profileFd;
10173            mSamplingInterval = profilerInfo.samplingInterval;
10174            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10175            mProfileType = 0;
10176        }
10177    }
10178
10179    @Override
10180    public void setAlwaysFinish(boolean enabled) {
10181        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10182                "setAlwaysFinish()");
10183
10184        Settings.Global.putInt(
10185                mContext.getContentResolver(),
10186                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10187
10188        synchronized (this) {
10189            mAlwaysFinishActivities = enabled;
10190        }
10191    }
10192
10193    @Override
10194    public void setActivityController(IActivityController controller) {
10195        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10196                "setActivityController()");
10197        synchronized (this) {
10198            mController = controller;
10199            Watchdog.getInstance().setActivityController(controller);
10200        }
10201    }
10202
10203    @Override
10204    public void setUserIsMonkey(boolean userIsMonkey) {
10205        synchronized (this) {
10206            synchronized (mPidsSelfLocked) {
10207                final int callingPid = Binder.getCallingPid();
10208                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10209                if (precessRecord == null) {
10210                    throw new SecurityException("Unknown process: " + callingPid);
10211                }
10212                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10213                    throw new SecurityException("Only an instrumentation process "
10214                            + "with a UiAutomation can call setUserIsMonkey");
10215                }
10216            }
10217            mUserIsMonkey = userIsMonkey;
10218        }
10219    }
10220
10221    @Override
10222    public boolean isUserAMonkey() {
10223        synchronized (this) {
10224            // If there is a controller also implies the user is a monkey.
10225            return (mUserIsMonkey || mController != null);
10226        }
10227    }
10228
10229    public void requestBugReport() {
10230        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10231        SystemProperties.set("ctl.start", "bugreport");
10232    }
10233
10234    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10235        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10236    }
10237
10238    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10239        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10240            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10241        }
10242        return KEY_DISPATCHING_TIMEOUT;
10243    }
10244
10245    @Override
10246    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10247        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10248                != PackageManager.PERMISSION_GRANTED) {
10249            throw new SecurityException("Requires permission "
10250                    + android.Manifest.permission.FILTER_EVENTS);
10251        }
10252        ProcessRecord proc;
10253        long timeout;
10254        synchronized (this) {
10255            synchronized (mPidsSelfLocked) {
10256                proc = mPidsSelfLocked.get(pid);
10257            }
10258            timeout = getInputDispatchingTimeoutLocked(proc);
10259        }
10260
10261        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10262            return -1;
10263        }
10264
10265        return timeout;
10266    }
10267
10268    /**
10269     * Handle input dispatching timeouts.
10270     * Returns whether input dispatching should be aborted or not.
10271     */
10272    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10273            final ActivityRecord activity, final ActivityRecord parent,
10274            final boolean aboveSystem, String reason) {
10275        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10276                != PackageManager.PERMISSION_GRANTED) {
10277            throw new SecurityException("Requires permission "
10278                    + android.Manifest.permission.FILTER_EVENTS);
10279        }
10280
10281        final String annotation;
10282        if (reason == null) {
10283            annotation = "Input dispatching timed out";
10284        } else {
10285            annotation = "Input dispatching timed out (" + reason + ")";
10286        }
10287
10288        if (proc != null) {
10289            synchronized (this) {
10290                if (proc.debugging) {
10291                    return false;
10292                }
10293
10294                if (mDidDexOpt) {
10295                    // Give more time since we were dexopting.
10296                    mDidDexOpt = false;
10297                    return false;
10298                }
10299
10300                if (proc.instrumentationClass != null) {
10301                    Bundle info = new Bundle();
10302                    info.putString("shortMsg", "keyDispatchingTimedOut");
10303                    info.putString("longMsg", annotation);
10304                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10305                    return true;
10306                }
10307            }
10308            mHandler.post(new Runnable() {
10309                @Override
10310                public void run() {
10311                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10312                }
10313            });
10314        }
10315
10316        return true;
10317    }
10318
10319    public Bundle getAssistContextExtras(int requestType) {
10320        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10321                UserHandle.getCallingUserId());
10322        if (pae == null) {
10323            return null;
10324        }
10325        synchronized (pae) {
10326            while (!pae.haveResult) {
10327                try {
10328                    pae.wait();
10329                } catch (InterruptedException e) {
10330                }
10331            }
10332            if (pae.result != null) {
10333                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10334            }
10335        }
10336        synchronized (this) {
10337            mPendingAssistExtras.remove(pae);
10338            mHandler.removeCallbacks(pae);
10339        }
10340        return pae.extras;
10341    }
10342
10343    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10344            int userHandle) {
10345        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10346                "getAssistContextExtras()");
10347        PendingAssistExtras pae;
10348        Bundle extras = new Bundle();
10349        synchronized (this) {
10350            ActivityRecord activity = getFocusedStack().mResumedActivity;
10351            if (activity == null) {
10352                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10353                return null;
10354            }
10355            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10356            if (activity.app == null || activity.app.thread == null) {
10357                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10358                return null;
10359            }
10360            if (activity.app.pid == Binder.getCallingPid()) {
10361                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10362                return null;
10363            }
10364            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10365            try {
10366                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10367                        requestType);
10368                mPendingAssistExtras.add(pae);
10369                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10370            } catch (RemoteException e) {
10371                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10372                return null;
10373            }
10374            return pae;
10375        }
10376    }
10377
10378    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10379        PendingAssistExtras pae = (PendingAssistExtras)token;
10380        synchronized (pae) {
10381            pae.result = extras;
10382            pae.haveResult = true;
10383            pae.notifyAll();
10384            if (pae.intent == null) {
10385                // Caller is just waiting for the result.
10386                return;
10387            }
10388        }
10389
10390        // We are now ready to launch the assist activity.
10391        synchronized (this) {
10392            boolean exists = mPendingAssistExtras.remove(pae);
10393            mHandler.removeCallbacks(pae);
10394            if (!exists) {
10395                // Timed out.
10396                return;
10397            }
10398        }
10399        pae.intent.replaceExtras(extras);
10400        if (pae.hint != null) {
10401            pae.intent.putExtra(pae.hint, true);
10402        }
10403        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10404                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10405                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10406        closeSystemDialogs("assist");
10407        try {
10408            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10409        } catch (ActivityNotFoundException e) {
10410            Slog.w(TAG, "No activity to handle assist action.", e);
10411        }
10412    }
10413
10414    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10415        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10416    }
10417
10418    public void registerProcessObserver(IProcessObserver observer) {
10419        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10420                "registerProcessObserver()");
10421        synchronized (this) {
10422            mProcessObservers.register(observer);
10423        }
10424    }
10425
10426    @Override
10427    public void unregisterProcessObserver(IProcessObserver observer) {
10428        synchronized (this) {
10429            mProcessObservers.unregister(observer);
10430        }
10431    }
10432
10433    @Override
10434    public boolean convertFromTranslucent(IBinder token) {
10435        final long origId = Binder.clearCallingIdentity();
10436        try {
10437            synchronized (this) {
10438                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10439                if (r == null) {
10440                    return false;
10441                }
10442                final boolean translucentChanged = r.changeWindowTranslucency(true);
10443                if (translucentChanged) {
10444                    r.task.stack.releaseBackgroundResources();
10445                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10446                }
10447                mWindowManager.setAppFullscreen(token, true);
10448                return translucentChanged;
10449            }
10450        } finally {
10451            Binder.restoreCallingIdentity(origId);
10452        }
10453    }
10454
10455    @Override
10456    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10457        final long origId = Binder.clearCallingIdentity();
10458        try {
10459            synchronized (this) {
10460                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10461                if (r == null) {
10462                    return false;
10463                }
10464                int index = r.task.mActivities.lastIndexOf(r);
10465                if (index > 0) {
10466                    ActivityRecord under = r.task.mActivities.get(index - 1);
10467                    under.returningOptions = options;
10468                }
10469                final boolean translucentChanged = r.changeWindowTranslucency(false);
10470                if (translucentChanged) {
10471                    r.task.stack.convertToTranslucent(r);
10472                }
10473                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10474                mWindowManager.setAppFullscreen(token, false);
10475                return translucentChanged;
10476            }
10477        } finally {
10478            Binder.restoreCallingIdentity(origId);
10479        }
10480    }
10481
10482    @Override
10483    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10484        final long origId = Binder.clearCallingIdentity();
10485        try {
10486            synchronized (this) {
10487                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10488                if (r != null) {
10489                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10490                }
10491            }
10492            return false;
10493        } finally {
10494            Binder.restoreCallingIdentity(origId);
10495        }
10496    }
10497
10498    @Override
10499    public boolean isBackgroundVisibleBehind(IBinder token) {
10500        final long origId = Binder.clearCallingIdentity();
10501        try {
10502            synchronized (this) {
10503                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10504                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10505                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10506                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10507                return visible;
10508            }
10509        } finally {
10510            Binder.restoreCallingIdentity(origId);
10511        }
10512    }
10513
10514    @Override
10515    public ActivityOptions getActivityOptions(IBinder token) {
10516        final long origId = Binder.clearCallingIdentity();
10517        try {
10518            synchronized (this) {
10519                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10520                if (r != null) {
10521                    final ActivityOptions activityOptions = r.pendingOptions;
10522                    r.pendingOptions = null;
10523                    return activityOptions;
10524                }
10525                return null;
10526            }
10527        } finally {
10528            Binder.restoreCallingIdentity(origId);
10529        }
10530    }
10531
10532    @Override
10533    public void setImmersive(IBinder token, boolean immersive) {
10534        synchronized(this) {
10535            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10536            if (r == null) {
10537                throw new IllegalArgumentException();
10538            }
10539            r.immersive = immersive;
10540
10541            // update associated state if we're frontmost
10542            if (r == mFocusedActivity) {
10543                if (DEBUG_IMMERSIVE) {
10544                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10545                }
10546                applyUpdateLockStateLocked(r);
10547            }
10548        }
10549    }
10550
10551    @Override
10552    public boolean isImmersive(IBinder token) {
10553        synchronized (this) {
10554            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10555            if (r == null) {
10556                throw new IllegalArgumentException();
10557            }
10558            return r.immersive;
10559        }
10560    }
10561
10562    public boolean isTopActivityImmersive() {
10563        enforceNotIsolatedCaller("startActivity");
10564        synchronized (this) {
10565            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10566            return (r != null) ? r.immersive : false;
10567        }
10568    }
10569
10570    @Override
10571    public boolean isTopOfTask(IBinder token) {
10572        synchronized (this) {
10573            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10574            if (r == null) {
10575                throw new IllegalArgumentException();
10576            }
10577            return r.task.getTopActivity() == r;
10578        }
10579    }
10580
10581    public final void enterSafeMode() {
10582        synchronized(this) {
10583            // It only makes sense to do this before the system is ready
10584            // and started launching other packages.
10585            if (!mSystemReady) {
10586                try {
10587                    AppGlobals.getPackageManager().enterSafeMode();
10588                } catch (RemoteException e) {
10589                }
10590            }
10591
10592            mSafeMode = true;
10593        }
10594    }
10595
10596    public final void showSafeModeOverlay() {
10597        View v = LayoutInflater.from(mContext).inflate(
10598                com.android.internal.R.layout.safe_mode, null);
10599        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10600        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10601        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10602        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10603        lp.gravity = Gravity.BOTTOM | Gravity.START;
10604        lp.format = v.getBackground().getOpacity();
10605        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10606                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10607        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10608        ((WindowManager)mContext.getSystemService(
10609                Context.WINDOW_SERVICE)).addView(v, lp);
10610    }
10611
10612    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10613        if (!(sender instanceof PendingIntentRecord)) {
10614            return;
10615        }
10616        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10617        synchronized (stats) {
10618            if (mBatteryStatsService.isOnBattery()) {
10619                mBatteryStatsService.enforceCallingPermission();
10620                PendingIntentRecord rec = (PendingIntentRecord)sender;
10621                int MY_UID = Binder.getCallingUid();
10622                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10623                BatteryStatsImpl.Uid.Pkg pkg =
10624                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10625                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10626                pkg.incWakeupsLocked();
10627            }
10628        }
10629    }
10630
10631    public boolean killPids(int[] pids, String pReason, boolean secure) {
10632        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10633            throw new SecurityException("killPids only available to the system");
10634        }
10635        String reason = (pReason == null) ? "Unknown" : pReason;
10636        // XXX Note: don't acquire main activity lock here, because the window
10637        // manager calls in with its locks held.
10638
10639        boolean killed = false;
10640        synchronized (mPidsSelfLocked) {
10641            int[] types = new int[pids.length];
10642            int worstType = 0;
10643            for (int i=0; i<pids.length; i++) {
10644                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10645                if (proc != null) {
10646                    int type = proc.setAdj;
10647                    types[i] = type;
10648                    if (type > worstType) {
10649                        worstType = type;
10650                    }
10651                }
10652            }
10653
10654            // If the worst oom_adj is somewhere in the cached proc LRU range,
10655            // then constrain it so we will kill all cached procs.
10656            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10657                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10658                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10659            }
10660
10661            // If this is not a secure call, don't let it kill processes that
10662            // are important.
10663            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10664                worstType = ProcessList.SERVICE_ADJ;
10665            }
10666
10667            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10668            for (int i=0; i<pids.length; i++) {
10669                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10670                if (proc == null) {
10671                    continue;
10672                }
10673                int adj = proc.setAdj;
10674                if (adj >= worstType && !proc.killedByAm) {
10675                    proc.kill(reason, true);
10676                    killed = true;
10677                }
10678            }
10679        }
10680        return killed;
10681    }
10682
10683    @Override
10684    public void killUid(int uid, String reason) {
10685        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10686            throw new SecurityException("killUid only available to the system");
10687        }
10688        synchronized (this) {
10689            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10690                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10691                    reason != null ? reason : "kill uid");
10692        }
10693    }
10694
10695    @Override
10696    public boolean killProcessesBelowForeground(String reason) {
10697        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10698            throw new SecurityException("killProcessesBelowForeground() only available to system");
10699        }
10700
10701        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10702    }
10703
10704    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10705        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10706            throw new SecurityException("killProcessesBelowAdj() only available to system");
10707        }
10708
10709        boolean killed = false;
10710        synchronized (mPidsSelfLocked) {
10711            final int size = mPidsSelfLocked.size();
10712            for (int i = 0; i < size; i++) {
10713                final int pid = mPidsSelfLocked.keyAt(i);
10714                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10715                if (proc == null) continue;
10716
10717                final int adj = proc.setAdj;
10718                if (adj > belowAdj && !proc.killedByAm) {
10719                    proc.kill(reason, true);
10720                    killed = true;
10721                }
10722            }
10723        }
10724        return killed;
10725    }
10726
10727    @Override
10728    public void hang(final IBinder who, boolean allowRestart) {
10729        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10730                != PackageManager.PERMISSION_GRANTED) {
10731            throw new SecurityException("Requires permission "
10732                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10733        }
10734
10735        final IBinder.DeathRecipient death = new DeathRecipient() {
10736            @Override
10737            public void binderDied() {
10738                synchronized (this) {
10739                    notifyAll();
10740                }
10741            }
10742        };
10743
10744        try {
10745            who.linkToDeath(death, 0);
10746        } catch (RemoteException e) {
10747            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10748            return;
10749        }
10750
10751        synchronized (this) {
10752            Watchdog.getInstance().setAllowRestart(allowRestart);
10753            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10754            synchronized (death) {
10755                while (who.isBinderAlive()) {
10756                    try {
10757                        death.wait();
10758                    } catch (InterruptedException e) {
10759                    }
10760                }
10761            }
10762            Watchdog.getInstance().setAllowRestart(true);
10763        }
10764    }
10765
10766    @Override
10767    public void restart() {
10768        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10769                != PackageManager.PERMISSION_GRANTED) {
10770            throw new SecurityException("Requires permission "
10771                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10772        }
10773
10774        Log.i(TAG, "Sending shutdown broadcast...");
10775
10776        BroadcastReceiver br = new BroadcastReceiver() {
10777            @Override public void onReceive(Context context, Intent intent) {
10778                // Now the broadcast is done, finish up the low-level shutdown.
10779                Log.i(TAG, "Shutting down activity manager...");
10780                shutdown(10000);
10781                Log.i(TAG, "Shutdown complete, restarting!");
10782                Process.killProcess(Process.myPid());
10783                System.exit(10);
10784            }
10785        };
10786
10787        // First send the high-level shut down broadcast.
10788        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10789        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10790        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10791        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10792        mContext.sendOrderedBroadcastAsUser(intent,
10793                UserHandle.ALL, null, br, mHandler, 0, null, null);
10794        */
10795        br.onReceive(mContext, intent);
10796    }
10797
10798    private long getLowRamTimeSinceIdle(long now) {
10799        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10800    }
10801
10802    @Override
10803    public void performIdleMaintenance() {
10804        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10805                != PackageManager.PERMISSION_GRANTED) {
10806            throw new SecurityException("Requires permission "
10807                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10808        }
10809
10810        synchronized (this) {
10811            final long now = SystemClock.uptimeMillis();
10812            final long timeSinceLastIdle = now - mLastIdleTime;
10813            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10814            mLastIdleTime = now;
10815            mLowRamTimeSinceLastIdle = 0;
10816            if (mLowRamStartTime != 0) {
10817                mLowRamStartTime = now;
10818            }
10819
10820            StringBuilder sb = new StringBuilder(128);
10821            sb.append("Idle maintenance over ");
10822            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10823            sb.append(" low RAM for ");
10824            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10825            Slog.i(TAG, sb.toString());
10826
10827            // If at least 1/3 of our time since the last idle period has been spent
10828            // with RAM low, then we want to kill processes.
10829            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10830
10831            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10832                ProcessRecord proc = mLruProcesses.get(i);
10833                if (proc.notCachedSinceIdle) {
10834                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10835                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10836                        if (doKilling && proc.initialIdlePss != 0
10837                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10838                            proc.kill("idle maint (pss " + proc.lastPss
10839                                    + " from " + proc.initialIdlePss + ")", true);
10840                        }
10841                    }
10842                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10843                    proc.notCachedSinceIdle = true;
10844                    proc.initialIdlePss = 0;
10845                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10846                            isSleeping(), now);
10847                }
10848            }
10849
10850            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10851            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10852        }
10853    }
10854
10855    private void retrieveSettings() {
10856        final ContentResolver resolver = mContext.getContentResolver();
10857        String debugApp = Settings.Global.getString(
10858            resolver, Settings.Global.DEBUG_APP);
10859        boolean waitForDebugger = Settings.Global.getInt(
10860            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10861        boolean alwaysFinishActivities = Settings.Global.getInt(
10862            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10863        boolean forceRtl = Settings.Global.getInt(
10864                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10865        // Transfer any global setting for forcing RTL layout, into a System Property
10866        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10867
10868        Configuration configuration = new Configuration();
10869        Settings.System.getConfiguration(resolver, configuration);
10870        if (forceRtl) {
10871            // This will take care of setting the correct layout direction flags
10872            configuration.setLayoutDirection(configuration.locale);
10873        }
10874
10875        synchronized (this) {
10876            mDebugApp = mOrigDebugApp = debugApp;
10877            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10878            mAlwaysFinishActivities = alwaysFinishActivities;
10879            // This happens before any activities are started, so we can
10880            // change mConfiguration in-place.
10881            updateConfigurationLocked(configuration, null, false, true);
10882            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10883        }
10884    }
10885
10886    /** Loads resources after the current configuration has been set. */
10887    private void loadResourcesOnSystemReady() {
10888        final Resources res = mContext.getResources();
10889        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10890        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10891        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10892    }
10893
10894    public boolean testIsSystemReady() {
10895        // no need to synchronize(this) just to read & return the value
10896        return mSystemReady;
10897    }
10898
10899    private static File getCalledPreBootReceiversFile() {
10900        File dataDir = Environment.getDataDirectory();
10901        File systemDir = new File(dataDir, "system");
10902        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10903        return fname;
10904    }
10905
10906    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10907        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10908        File file = getCalledPreBootReceiversFile();
10909        FileInputStream fis = null;
10910        try {
10911            fis = new FileInputStream(file);
10912            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10913            int fvers = dis.readInt();
10914            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10915                String vers = dis.readUTF();
10916                String codename = dis.readUTF();
10917                String build = dis.readUTF();
10918                if (android.os.Build.VERSION.RELEASE.equals(vers)
10919                        && android.os.Build.VERSION.CODENAME.equals(codename)
10920                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10921                    int num = dis.readInt();
10922                    while (num > 0) {
10923                        num--;
10924                        String pkg = dis.readUTF();
10925                        String cls = dis.readUTF();
10926                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10927                    }
10928                }
10929            }
10930        } catch (FileNotFoundException e) {
10931        } catch (IOException e) {
10932            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10933        } finally {
10934            if (fis != null) {
10935                try {
10936                    fis.close();
10937                } catch (IOException e) {
10938                }
10939            }
10940        }
10941        return lastDoneReceivers;
10942    }
10943
10944    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10945        File file = getCalledPreBootReceiversFile();
10946        FileOutputStream fos = null;
10947        DataOutputStream dos = null;
10948        try {
10949            fos = new FileOutputStream(file);
10950            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10951            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10952            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10953            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10954            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10955            dos.writeInt(list.size());
10956            for (int i=0; i<list.size(); i++) {
10957                dos.writeUTF(list.get(i).getPackageName());
10958                dos.writeUTF(list.get(i).getClassName());
10959            }
10960        } catch (IOException e) {
10961            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10962            file.delete();
10963        } finally {
10964            FileUtils.sync(fos);
10965            if (dos != null) {
10966                try {
10967                    dos.close();
10968                } catch (IOException e) {
10969                    // TODO Auto-generated catch block
10970                    e.printStackTrace();
10971                }
10972            }
10973        }
10974    }
10975
10976    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10977            ArrayList<ComponentName> doneReceivers, int userId) {
10978        boolean waitingUpdate = false;
10979        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10980        List<ResolveInfo> ris = null;
10981        try {
10982            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10983                    intent, null, 0, userId);
10984        } catch (RemoteException e) {
10985        }
10986        if (ris != null) {
10987            for (int i=ris.size()-1; i>=0; i--) {
10988                if ((ris.get(i).activityInfo.applicationInfo.flags
10989                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10990                    ris.remove(i);
10991                }
10992            }
10993            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10994
10995            // For User 0, load the version number. When delivering to a new user, deliver
10996            // to all receivers.
10997            if (userId == UserHandle.USER_OWNER) {
10998                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10999                for (int i=0; i<ris.size(); i++) {
11000                    ActivityInfo ai = ris.get(i).activityInfo;
11001                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11002                    if (lastDoneReceivers.contains(comp)) {
11003                        // We already did the pre boot receiver for this app with the current
11004                        // platform version, so don't do it again...
11005                        ris.remove(i);
11006                        i--;
11007                        // ...however, do keep it as one that has been done, so we don't
11008                        // forget about it when rewriting the file of last done receivers.
11009                        doneReceivers.add(comp);
11010                    }
11011                }
11012            }
11013
11014            // If primary user, send broadcast to all available users, else just to userId
11015            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11016                    : new int[] { userId };
11017            for (int i = 0; i < ris.size(); i++) {
11018                ActivityInfo ai = ris.get(i).activityInfo;
11019                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11020                doneReceivers.add(comp);
11021                intent.setComponent(comp);
11022                for (int j=0; j<users.length; j++) {
11023                    IIntentReceiver finisher = null;
11024                    // On last receiver and user, set up a completion callback
11025                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11026                        finisher = new IIntentReceiver.Stub() {
11027                            public void performReceive(Intent intent, int resultCode,
11028                                    String data, Bundle extras, boolean ordered,
11029                                    boolean sticky, int sendingUser) {
11030                                // The raw IIntentReceiver interface is called
11031                                // with the AM lock held, so redispatch to
11032                                // execute our code without the lock.
11033                                mHandler.post(onFinishCallback);
11034                            }
11035                        };
11036                    }
11037                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11038                            + " for user " + users[j]);
11039                    broadcastIntentLocked(null, null, intent, null, finisher,
11040                            0, null, null, null, AppOpsManager.OP_NONE,
11041                            true, false, MY_PID, Process.SYSTEM_UID,
11042                            users[j]);
11043                    if (finisher != null) {
11044                        waitingUpdate = true;
11045                    }
11046                }
11047            }
11048        }
11049
11050        return waitingUpdate;
11051    }
11052
11053    public void systemReady(final Runnable goingCallback) {
11054        synchronized(this) {
11055            if (mSystemReady) {
11056                // If we're done calling all the receivers, run the next "boot phase" passed in
11057                // by the SystemServer
11058                if (goingCallback != null) {
11059                    goingCallback.run();
11060                }
11061                return;
11062            }
11063
11064            // Make sure we have the current profile info, since it is needed for
11065            // security checks.
11066            updateCurrentProfileIdsLocked();
11067
11068            if (mRecentTasks == null) {
11069                mRecentTasks = mTaskPersister.restoreTasksLocked();
11070                if (!mRecentTasks.isEmpty()) {
11071                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11072                }
11073                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11074                mTaskPersister.startPersisting();
11075            }
11076
11077            // Check to see if there are any update receivers to run.
11078            if (!mDidUpdate) {
11079                if (mWaitingUpdate) {
11080                    return;
11081                }
11082                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11083                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11084                    public void run() {
11085                        synchronized (ActivityManagerService.this) {
11086                            mDidUpdate = true;
11087                        }
11088                        writeLastDonePreBootReceivers(doneReceivers);
11089                        showBootMessage(mContext.getText(
11090                                R.string.android_upgrading_complete),
11091                                false);
11092                        systemReady(goingCallback);
11093                    }
11094                }, doneReceivers, UserHandle.USER_OWNER);
11095
11096                if (mWaitingUpdate) {
11097                    return;
11098                }
11099                mDidUpdate = true;
11100            }
11101
11102            mAppOpsService.systemReady();
11103            mSystemReady = true;
11104        }
11105
11106        ArrayList<ProcessRecord> procsToKill = null;
11107        synchronized(mPidsSelfLocked) {
11108            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11109                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11110                if (!isAllowedWhileBooting(proc.info)){
11111                    if (procsToKill == null) {
11112                        procsToKill = new ArrayList<ProcessRecord>();
11113                    }
11114                    procsToKill.add(proc);
11115                }
11116            }
11117        }
11118
11119        synchronized(this) {
11120            if (procsToKill != null) {
11121                for (int i=procsToKill.size()-1; i>=0; i--) {
11122                    ProcessRecord proc = procsToKill.get(i);
11123                    Slog.i(TAG, "Removing system update proc: " + proc);
11124                    removeProcessLocked(proc, true, false, "system update done");
11125                }
11126            }
11127
11128            // Now that we have cleaned up any update processes, we
11129            // are ready to start launching real processes and know that
11130            // we won't trample on them any more.
11131            mProcessesReady = true;
11132        }
11133
11134        Slog.i(TAG, "System now ready");
11135        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11136            SystemClock.uptimeMillis());
11137
11138        synchronized(this) {
11139            // Make sure we have no pre-ready processes sitting around.
11140
11141            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11142                ResolveInfo ri = mContext.getPackageManager()
11143                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11144                                STOCK_PM_FLAGS);
11145                CharSequence errorMsg = null;
11146                if (ri != null) {
11147                    ActivityInfo ai = ri.activityInfo;
11148                    ApplicationInfo app = ai.applicationInfo;
11149                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11150                        mTopAction = Intent.ACTION_FACTORY_TEST;
11151                        mTopData = null;
11152                        mTopComponent = new ComponentName(app.packageName,
11153                                ai.name);
11154                    } else {
11155                        errorMsg = mContext.getResources().getText(
11156                                com.android.internal.R.string.factorytest_not_system);
11157                    }
11158                } else {
11159                    errorMsg = mContext.getResources().getText(
11160                            com.android.internal.R.string.factorytest_no_action);
11161                }
11162                if (errorMsg != null) {
11163                    mTopAction = null;
11164                    mTopData = null;
11165                    mTopComponent = null;
11166                    Message msg = Message.obtain();
11167                    msg.what = SHOW_FACTORY_ERROR_MSG;
11168                    msg.getData().putCharSequence("msg", errorMsg);
11169                    mHandler.sendMessage(msg);
11170                }
11171            }
11172        }
11173
11174        retrieveSettings();
11175        loadResourcesOnSystemReady();
11176
11177        synchronized (this) {
11178            readGrantedUriPermissionsLocked();
11179        }
11180
11181        if (goingCallback != null) goingCallback.run();
11182
11183        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11184                Integer.toString(mCurrentUserId), mCurrentUserId);
11185        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11186                Integer.toString(mCurrentUserId), mCurrentUserId);
11187        mSystemServiceManager.startUser(mCurrentUserId);
11188
11189        synchronized (this) {
11190            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11191                try {
11192                    List apps = AppGlobals.getPackageManager().
11193                        getPersistentApplications(STOCK_PM_FLAGS);
11194                    if (apps != null) {
11195                        int N = apps.size();
11196                        int i;
11197                        for (i=0; i<N; i++) {
11198                            ApplicationInfo info
11199                                = (ApplicationInfo)apps.get(i);
11200                            if (info != null &&
11201                                    !info.packageName.equals("android")) {
11202                                addAppLocked(info, false, null /* ABI override */);
11203                            }
11204                        }
11205                    }
11206                } catch (RemoteException ex) {
11207                    // pm is in same process, this will never happen.
11208                }
11209            }
11210
11211            // Start up initial activity.
11212            mBooting = true;
11213            startHomeActivityLocked(mCurrentUserId);
11214
11215            try {
11216                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11217                    Message msg = Message.obtain();
11218                    msg.what = SHOW_UID_ERROR_MSG;
11219                    mHandler.sendMessage(msg);
11220                }
11221            } catch (RemoteException e) {
11222            }
11223
11224            long ident = Binder.clearCallingIdentity();
11225            try {
11226                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11227                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11228                        | Intent.FLAG_RECEIVER_FOREGROUND);
11229                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11230                broadcastIntentLocked(null, null, intent,
11231                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11232                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11233                intent = new Intent(Intent.ACTION_USER_STARTING);
11234                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11235                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11236                broadcastIntentLocked(null, null, intent,
11237                        null, new IIntentReceiver.Stub() {
11238                            @Override
11239                            public void performReceive(Intent intent, int resultCode, String data,
11240                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11241                                    throws RemoteException {
11242                            }
11243                        }, 0, null, null,
11244                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11245                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11246            } catch (Throwable t) {
11247                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11248            } finally {
11249                Binder.restoreCallingIdentity(ident);
11250            }
11251            mStackSupervisor.resumeTopActivitiesLocked();
11252            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11253        }
11254    }
11255
11256    private boolean makeAppCrashingLocked(ProcessRecord app,
11257            String shortMsg, String longMsg, String stackTrace) {
11258        app.crashing = true;
11259        app.crashingReport = generateProcessError(app,
11260                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11261        startAppProblemLocked(app);
11262        app.stopFreezingAllLocked();
11263        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11264    }
11265
11266    private void makeAppNotRespondingLocked(ProcessRecord app,
11267            String activity, String shortMsg, String longMsg) {
11268        app.notResponding = true;
11269        app.notRespondingReport = generateProcessError(app,
11270                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11271                activity, shortMsg, longMsg, null);
11272        startAppProblemLocked(app);
11273        app.stopFreezingAllLocked();
11274    }
11275
11276    /**
11277     * Generate a process error record, suitable for attachment to a ProcessRecord.
11278     *
11279     * @param app The ProcessRecord in which the error occurred.
11280     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11281     *                      ActivityManager.AppErrorStateInfo
11282     * @param activity The activity associated with the crash, if known.
11283     * @param shortMsg Short message describing the crash.
11284     * @param longMsg Long message describing the crash.
11285     * @param stackTrace Full crash stack trace, may be null.
11286     *
11287     * @return Returns a fully-formed AppErrorStateInfo record.
11288     */
11289    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11290            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11291        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11292
11293        report.condition = condition;
11294        report.processName = app.processName;
11295        report.pid = app.pid;
11296        report.uid = app.info.uid;
11297        report.tag = activity;
11298        report.shortMsg = shortMsg;
11299        report.longMsg = longMsg;
11300        report.stackTrace = stackTrace;
11301
11302        return report;
11303    }
11304
11305    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11306        synchronized (this) {
11307            app.crashing = false;
11308            app.crashingReport = null;
11309            app.notResponding = false;
11310            app.notRespondingReport = null;
11311            if (app.anrDialog == fromDialog) {
11312                app.anrDialog = null;
11313            }
11314            if (app.waitDialog == fromDialog) {
11315                app.waitDialog = null;
11316            }
11317            if (app.pid > 0 && app.pid != MY_PID) {
11318                handleAppCrashLocked(app, null, null, null);
11319                app.kill("user request after error", true);
11320            }
11321        }
11322    }
11323
11324    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11325            String stackTrace) {
11326        long now = SystemClock.uptimeMillis();
11327
11328        Long crashTime;
11329        if (!app.isolated) {
11330            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11331        } else {
11332            crashTime = null;
11333        }
11334        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11335            // This process loses!
11336            Slog.w(TAG, "Process " + app.info.processName
11337                    + " has crashed too many times: killing!");
11338            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11339                    app.userId, app.info.processName, app.uid);
11340            mStackSupervisor.handleAppCrashLocked(app);
11341            if (!app.persistent) {
11342                // We don't want to start this process again until the user
11343                // explicitly does so...  but for persistent process, we really
11344                // need to keep it running.  If a persistent process is actually
11345                // repeatedly crashing, then badness for everyone.
11346                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11347                        app.info.processName);
11348                if (!app.isolated) {
11349                    // XXX We don't have a way to mark isolated processes
11350                    // as bad, since they don't have a peristent identity.
11351                    mBadProcesses.put(app.info.processName, app.uid,
11352                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11353                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11354                }
11355                app.bad = true;
11356                app.removed = true;
11357                // Don't let services in this process be restarted and potentially
11358                // annoy the user repeatedly.  Unless it is persistent, since those
11359                // processes run critical code.
11360                removeProcessLocked(app, false, false, "crash");
11361                mStackSupervisor.resumeTopActivitiesLocked();
11362                return false;
11363            }
11364            mStackSupervisor.resumeTopActivitiesLocked();
11365        } else {
11366            mStackSupervisor.finishTopRunningActivityLocked(app);
11367        }
11368
11369        // Bump up the crash count of any services currently running in the proc.
11370        for (int i=app.services.size()-1; i>=0; i--) {
11371            // Any services running in the application need to be placed
11372            // back in the pending list.
11373            ServiceRecord sr = app.services.valueAt(i);
11374            sr.crashCount++;
11375        }
11376
11377        // If the crashing process is what we consider to be the "home process" and it has been
11378        // replaced by a third-party app, clear the package preferred activities from packages
11379        // with a home activity running in the process to prevent a repeatedly crashing app
11380        // from blocking the user to manually clear the list.
11381        final ArrayList<ActivityRecord> activities = app.activities;
11382        if (app == mHomeProcess && activities.size() > 0
11383                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11384            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11385                final ActivityRecord r = activities.get(activityNdx);
11386                if (r.isHomeActivity()) {
11387                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11388                    try {
11389                        ActivityThread.getPackageManager()
11390                                .clearPackagePreferredActivities(r.packageName);
11391                    } catch (RemoteException c) {
11392                        // pm is in same process, this will never happen.
11393                    }
11394                }
11395            }
11396        }
11397
11398        if (!app.isolated) {
11399            // XXX Can't keep track of crash times for isolated processes,
11400            // because they don't have a perisistent identity.
11401            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11402        }
11403
11404        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11405        return true;
11406    }
11407
11408    void startAppProblemLocked(ProcessRecord app) {
11409        // If this app is not running under the current user, then we
11410        // can't give it a report button because that would require
11411        // launching the report UI under a different user.
11412        app.errorReportReceiver = null;
11413
11414        for (int userId : mCurrentProfileIds) {
11415            if (app.userId == userId) {
11416                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11417                        mContext, app.info.packageName, app.info.flags);
11418            }
11419        }
11420        skipCurrentReceiverLocked(app);
11421    }
11422
11423    void skipCurrentReceiverLocked(ProcessRecord app) {
11424        for (BroadcastQueue queue : mBroadcastQueues) {
11425            queue.skipCurrentReceiverLocked(app);
11426        }
11427    }
11428
11429    /**
11430     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11431     * The application process will exit immediately after this call returns.
11432     * @param app object of the crashing app, null for the system server
11433     * @param crashInfo describing the exception
11434     */
11435    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11436        ProcessRecord r = findAppProcess(app, "Crash");
11437        final String processName = app == null ? "system_server"
11438                : (r == null ? "unknown" : r.processName);
11439
11440        handleApplicationCrashInner("crash", r, processName, crashInfo);
11441    }
11442
11443    /* Native crash reporting uses this inner version because it needs to be somewhat
11444     * decoupled from the AM-managed cleanup lifecycle
11445     */
11446    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11447            ApplicationErrorReport.CrashInfo crashInfo) {
11448        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11449                UserHandle.getUserId(Binder.getCallingUid()), processName,
11450                r == null ? -1 : r.info.flags,
11451                crashInfo.exceptionClassName,
11452                crashInfo.exceptionMessage,
11453                crashInfo.throwFileName,
11454                crashInfo.throwLineNumber);
11455
11456        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11457
11458        crashApplication(r, crashInfo);
11459    }
11460
11461    public void handleApplicationStrictModeViolation(
11462            IBinder app,
11463            int violationMask,
11464            StrictMode.ViolationInfo info) {
11465        ProcessRecord r = findAppProcess(app, "StrictMode");
11466        if (r == null) {
11467            return;
11468        }
11469
11470        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11471            Integer stackFingerprint = info.hashCode();
11472            boolean logIt = true;
11473            synchronized (mAlreadyLoggedViolatedStacks) {
11474                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11475                    logIt = false;
11476                    // TODO: sub-sample into EventLog for these, with
11477                    // the info.durationMillis?  Then we'd get
11478                    // the relative pain numbers, without logging all
11479                    // the stack traces repeatedly.  We'd want to do
11480                    // likewise in the client code, which also does
11481                    // dup suppression, before the Binder call.
11482                } else {
11483                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11484                        mAlreadyLoggedViolatedStacks.clear();
11485                    }
11486                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11487                }
11488            }
11489            if (logIt) {
11490                logStrictModeViolationToDropBox(r, info);
11491            }
11492        }
11493
11494        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11495            AppErrorResult result = new AppErrorResult();
11496            synchronized (this) {
11497                final long origId = Binder.clearCallingIdentity();
11498
11499                Message msg = Message.obtain();
11500                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11501                HashMap<String, Object> data = new HashMap<String, Object>();
11502                data.put("result", result);
11503                data.put("app", r);
11504                data.put("violationMask", violationMask);
11505                data.put("info", info);
11506                msg.obj = data;
11507                mHandler.sendMessage(msg);
11508
11509                Binder.restoreCallingIdentity(origId);
11510            }
11511            int res = result.get();
11512            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11513        }
11514    }
11515
11516    // Depending on the policy in effect, there could be a bunch of
11517    // these in quick succession so we try to batch these together to
11518    // minimize disk writes, number of dropbox entries, and maximize
11519    // compression, by having more fewer, larger records.
11520    private void logStrictModeViolationToDropBox(
11521            ProcessRecord process,
11522            StrictMode.ViolationInfo info) {
11523        if (info == null) {
11524            return;
11525        }
11526        final boolean isSystemApp = process == null ||
11527                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11528                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11529        final String processName = process == null ? "unknown" : process.processName;
11530        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11531        final DropBoxManager dbox = (DropBoxManager)
11532                mContext.getSystemService(Context.DROPBOX_SERVICE);
11533
11534        // Exit early if the dropbox isn't configured to accept this report type.
11535        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11536
11537        boolean bufferWasEmpty;
11538        boolean needsFlush;
11539        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11540        synchronized (sb) {
11541            bufferWasEmpty = sb.length() == 0;
11542            appendDropBoxProcessHeaders(process, processName, sb);
11543            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11544            sb.append("System-App: ").append(isSystemApp).append("\n");
11545            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11546            if (info.violationNumThisLoop != 0) {
11547                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11548            }
11549            if (info.numAnimationsRunning != 0) {
11550                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11551            }
11552            if (info.broadcastIntentAction != null) {
11553                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11554            }
11555            if (info.durationMillis != -1) {
11556                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11557            }
11558            if (info.numInstances != -1) {
11559                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11560            }
11561            if (info.tags != null) {
11562                for (String tag : info.tags) {
11563                    sb.append("Span-Tag: ").append(tag).append("\n");
11564                }
11565            }
11566            sb.append("\n");
11567            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11568                sb.append(info.crashInfo.stackTrace);
11569            }
11570            sb.append("\n");
11571
11572            // Only buffer up to ~64k.  Various logging bits truncate
11573            // things at 128k.
11574            needsFlush = (sb.length() > 64 * 1024);
11575        }
11576
11577        // Flush immediately if the buffer's grown too large, or this
11578        // is a non-system app.  Non-system apps are isolated with a
11579        // different tag & policy and not batched.
11580        //
11581        // Batching is useful during internal testing with
11582        // StrictMode settings turned up high.  Without batching,
11583        // thousands of separate files could be created on boot.
11584        if (!isSystemApp || needsFlush) {
11585            new Thread("Error dump: " + dropboxTag) {
11586                @Override
11587                public void run() {
11588                    String report;
11589                    synchronized (sb) {
11590                        report = sb.toString();
11591                        sb.delete(0, sb.length());
11592                        sb.trimToSize();
11593                    }
11594                    if (report.length() != 0) {
11595                        dbox.addText(dropboxTag, report);
11596                    }
11597                }
11598            }.start();
11599            return;
11600        }
11601
11602        // System app batching:
11603        if (!bufferWasEmpty) {
11604            // An existing dropbox-writing thread is outstanding, so
11605            // we don't need to start it up.  The existing thread will
11606            // catch the buffer appends we just did.
11607            return;
11608        }
11609
11610        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11611        // (After this point, we shouldn't access AMS internal data structures.)
11612        new Thread("Error dump: " + dropboxTag) {
11613            @Override
11614            public void run() {
11615                // 5 second sleep to let stacks arrive and be batched together
11616                try {
11617                    Thread.sleep(5000);  // 5 seconds
11618                } catch (InterruptedException e) {}
11619
11620                String errorReport;
11621                synchronized (mStrictModeBuffer) {
11622                    errorReport = mStrictModeBuffer.toString();
11623                    if (errorReport.length() == 0) {
11624                        return;
11625                    }
11626                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11627                    mStrictModeBuffer.trimToSize();
11628                }
11629                dbox.addText(dropboxTag, errorReport);
11630            }
11631        }.start();
11632    }
11633
11634    /**
11635     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11636     * @param app object of the crashing app, null for the system server
11637     * @param tag reported by the caller
11638     * @param system whether this wtf is coming from the system
11639     * @param crashInfo describing the context of the error
11640     * @return true if the process should exit immediately (WTF is fatal)
11641     */
11642    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11643            final ApplicationErrorReport.CrashInfo crashInfo) {
11644        final int callingUid = Binder.getCallingUid();
11645        final int callingPid = Binder.getCallingPid();
11646
11647        if (system) {
11648            // If this is coming from the system, we could very well have low-level
11649            // system locks held, so we want to do this all asynchronously.  And we
11650            // never want this to become fatal, so there is that too.
11651            mHandler.post(new Runnable() {
11652                @Override public void run() {
11653                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11654                }
11655            });
11656            return false;
11657        }
11658
11659        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11660                crashInfo);
11661
11662        if (r != null && r.pid != Process.myPid() &&
11663                Settings.Global.getInt(mContext.getContentResolver(),
11664                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11665            crashApplication(r, crashInfo);
11666            return true;
11667        } else {
11668            return false;
11669        }
11670    }
11671
11672    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11673            final ApplicationErrorReport.CrashInfo crashInfo) {
11674        final ProcessRecord r = findAppProcess(app, "WTF");
11675        final String processName = app == null ? "system_server"
11676                : (r == null ? "unknown" : r.processName);
11677
11678        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11679                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11680
11681        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11682
11683        return r;
11684    }
11685
11686    /**
11687     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11688     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11689     */
11690    private ProcessRecord findAppProcess(IBinder app, String reason) {
11691        if (app == null) {
11692            return null;
11693        }
11694
11695        synchronized (this) {
11696            final int NP = mProcessNames.getMap().size();
11697            for (int ip=0; ip<NP; ip++) {
11698                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11699                final int NA = apps.size();
11700                for (int ia=0; ia<NA; ia++) {
11701                    ProcessRecord p = apps.valueAt(ia);
11702                    if (p.thread != null && p.thread.asBinder() == app) {
11703                        return p;
11704                    }
11705                }
11706            }
11707
11708            Slog.w(TAG, "Can't find mystery application for " + reason
11709                    + " from pid=" + Binder.getCallingPid()
11710                    + " uid=" + Binder.getCallingUid() + ": " + app);
11711            return null;
11712        }
11713    }
11714
11715    /**
11716     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11717     * to append various headers to the dropbox log text.
11718     */
11719    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11720            StringBuilder sb) {
11721        // Watchdog thread ends up invoking this function (with
11722        // a null ProcessRecord) to add the stack file to dropbox.
11723        // Do not acquire a lock on this (am) in such cases, as it
11724        // could cause a potential deadlock, if and when watchdog
11725        // is invoked due to unavailability of lock on am and it
11726        // would prevent watchdog from killing system_server.
11727        if (process == null) {
11728            sb.append("Process: ").append(processName).append("\n");
11729            return;
11730        }
11731        // Note: ProcessRecord 'process' is guarded by the service
11732        // instance.  (notably process.pkgList, which could otherwise change
11733        // concurrently during execution of this method)
11734        synchronized (this) {
11735            sb.append("Process: ").append(processName).append("\n");
11736            int flags = process.info.flags;
11737            IPackageManager pm = AppGlobals.getPackageManager();
11738            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11739            for (int ip=0; ip<process.pkgList.size(); ip++) {
11740                String pkg = process.pkgList.keyAt(ip);
11741                sb.append("Package: ").append(pkg);
11742                try {
11743                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11744                    if (pi != null) {
11745                        sb.append(" v").append(pi.versionCode);
11746                        if (pi.versionName != null) {
11747                            sb.append(" (").append(pi.versionName).append(")");
11748                        }
11749                    }
11750                } catch (RemoteException e) {
11751                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11752                }
11753                sb.append("\n");
11754            }
11755        }
11756    }
11757
11758    private static String processClass(ProcessRecord process) {
11759        if (process == null || process.pid == MY_PID) {
11760            return "system_server";
11761        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11762            return "system_app";
11763        } else {
11764            return "data_app";
11765        }
11766    }
11767
11768    /**
11769     * Write a description of an error (crash, WTF, ANR) to the drop box.
11770     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11771     * @param process which caused the error, null means the system server
11772     * @param activity which triggered the error, null if unknown
11773     * @param parent activity related to the error, null if unknown
11774     * @param subject line related to the error, null if absent
11775     * @param report in long form describing the error, null if absent
11776     * @param logFile to include in the report, null if none
11777     * @param crashInfo giving an application stack trace, null if absent
11778     */
11779    public void addErrorToDropBox(String eventType,
11780            ProcessRecord process, String processName, ActivityRecord activity,
11781            ActivityRecord parent, String subject,
11782            final String report, final File logFile,
11783            final ApplicationErrorReport.CrashInfo crashInfo) {
11784        // NOTE -- this must never acquire the ActivityManagerService lock,
11785        // otherwise the watchdog may be prevented from resetting the system.
11786
11787        final String dropboxTag = processClass(process) + "_" + eventType;
11788        final DropBoxManager dbox = (DropBoxManager)
11789                mContext.getSystemService(Context.DROPBOX_SERVICE);
11790
11791        // Exit early if the dropbox isn't configured to accept this report type.
11792        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11793
11794        final StringBuilder sb = new StringBuilder(1024);
11795        appendDropBoxProcessHeaders(process, processName, sb);
11796        if (activity != null) {
11797            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11798        }
11799        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11800            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11801        }
11802        if (parent != null && parent != activity) {
11803            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11804        }
11805        if (subject != null) {
11806            sb.append("Subject: ").append(subject).append("\n");
11807        }
11808        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11809        if (Debug.isDebuggerConnected()) {
11810            sb.append("Debugger: Connected\n");
11811        }
11812        sb.append("\n");
11813
11814        // Do the rest in a worker thread to avoid blocking the caller on I/O
11815        // (After this point, we shouldn't access AMS internal data structures.)
11816        Thread worker = new Thread("Error dump: " + dropboxTag) {
11817            @Override
11818            public void run() {
11819                if (report != null) {
11820                    sb.append(report);
11821                }
11822                if (logFile != null) {
11823                    try {
11824                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11825                                    "\n\n[[TRUNCATED]]"));
11826                    } catch (IOException e) {
11827                        Slog.e(TAG, "Error reading " + logFile, e);
11828                    }
11829                }
11830                if (crashInfo != null && crashInfo.stackTrace != null) {
11831                    sb.append(crashInfo.stackTrace);
11832                }
11833
11834                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11835                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11836                if (lines > 0) {
11837                    sb.append("\n");
11838
11839                    // Merge several logcat streams, and take the last N lines
11840                    InputStreamReader input = null;
11841                    try {
11842                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11843                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11844                                "-b", "crash",
11845                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11846
11847                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11848                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11849                        input = new InputStreamReader(logcat.getInputStream());
11850
11851                        int num;
11852                        char[] buf = new char[8192];
11853                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11854                    } catch (IOException e) {
11855                        Slog.e(TAG, "Error running logcat", e);
11856                    } finally {
11857                        if (input != null) try { input.close(); } catch (IOException e) {}
11858                    }
11859                }
11860
11861                dbox.addText(dropboxTag, sb.toString());
11862            }
11863        };
11864
11865        if (process == null) {
11866            // If process is null, we are being called from some internal code
11867            // and may be about to die -- run this synchronously.
11868            worker.run();
11869        } else {
11870            worker.start();
11871        }
11872    }
11873
11874    /**
11875     * Bring up the "unexpected error" dialog box for a crashing app.
11876     * Deal with edge cases (intercepts from instrumented applications,
11877     * ActivityController, error intent receivers, that sort of thing).
11878     * @param r the application crashing
11879     * @param crashInfo describing the failure
11880     */
11881    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11882        long timeMillis = System.currentTimeMillis();
11883        String shortMsg = crashInfo.exceptionClassName;
11884        String longMsg = crashInfo.exceptionMessage;
11885        String stackTrace = crashInfo.stackTrace;
11886        if (shortMsg != null && longMsg != null) {
11887            longMsg = shortMsg + ": " + longMsg;
11888        } else if (shortMsg != null) {
11889            longMsg = shortMsg;
11890        }
11891
11892        AppErrorResult result = new AppErrorResult();
11893        synchronized (this) {
11894            if (mController != null) {
11895                try {
11896                    String name = r != null ? r.processName : null;
11897                    int pid = r != null ? r.pid : Binder.getCallingPid();
11898                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11899                    if (!mController.appCrashed(name, pid,
11900                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11901                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11902                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11903                            Slog.w(TAG, "Skip killing native crashed app " + name
11904                                    + "(" + pid + ") during testing");
11905                        } else {
11906                            Slog.w(TAG, "Force-killing crashed app " + name
11907                                    + " at watcher's request");
11908                            if (r != null) {
11909                                r.kill("crash", true);
11910                            } else {
11911                                // Huh.
11912                                Process.killProcess(pid);
11913                                Process.killProcessGroup(uid, pid);
11914                            }
11915                        }
11916                        return;
11917                    }
11918                } catch (RemoteException e) {
11919                    mController = null;
11920                    Watchdog.getInstance().setActivityController(null);
11921                }
11922            }
11923
11924            final long origId = Binder.clearCallingIdentity();
11925
11926            // If this process is running instrumentation, finish it.
11927            if (r != null && r.instrumentationClass != null) {
11928                Slog.w(TAG, "Error in app " + r.processName
11929                      + " running instrumentation " + r.instrumentationClass + ":");
11930                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11931                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11932                Bundle info = new Bundle();
11933                info.putString("shortMsg", shortMsg);
11934                info.putString("longMsg", longMsg);
11935                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11936                Binder.restoreCallingIdentity(origId);
11937                return;
11938            }
11939
11940            // If we can't identify the process or it's already exceeded its crash quota,
11941            // quit right away without showing a crash dialog.
11942            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11943                Binder.restoreCallingIdentity(origId);
11944                return;
11945            }
11946
11947            Message msg = Message.obtain();
11948            msg.what = SHOW_ERROR_MSG;
11949            HashMap data = new HashMap();
11950            data.put("result", result);
11951            data.put("app", r);
11952            msg.obj = data;
11953            mHandler.sendMessage(msg);
11954
11955            Binder.restoreCallingIdentity(origId);
11956        }
11957
11958        int res = result.get();
11959
11960        Intent appErrorIntent = null;
11961        synchronized (this) {
11962            if (r != null && !r.isolated) {
11963                // XXX Can't keep track of crash time for isolated processes,
11964                // since they don't have a persistent identity.
11965                mProcessCrashTimes.put(r.info.processName, r.uid,
11966                        SystemClock.uptimeMillis());
11967            }
11968            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11969                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11970            }
11971        }
11972
11973        if (appErrorIntent != null) {
11974            try {
11975                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11976            } catch (ActivityNotFoundException e) {
11977                Slog.w(TAG, "bug report receiver dissappeared", e);
11978            }
11979        }
11980    }
11981
11982    Intent createAppErrorIntentLocked(ProcessRecord r,
11983            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11984        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11985        if (report == null) {
11986            return null;
11987        }
11988        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11989        result.setComponent(r.errorReportReceiver);
11990        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11991        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11992        return result;
11993    }
11994
11995    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11996            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11997        if (r.errorReportReceiver == null) {
11998            return null;
11999        }
12000
12001        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12002            return null;
12003        }
12004
12005        ApplicationErrorReport report = new ApplicationErrorReport();
12006        report.packageName = r.info.packageName;
12007        report.installerPackageName = r.errorReportReceiver.getPackageName();
12008        report.processName = r.processName;
12009        report.time = timeMillis;
12010        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12011
12012        if (r.crashing || r.forceCrashReport) {
12013            report.type = ApplicationErrorReport.TYPE_CRASH;
12014            report.crashInfo = crashInfo;
12015        } else if (r.notResponding) {
12016            report.type = ApplicationErrorReport.TYPE_ANR;
12017            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12018
12019            report.anrInfo.activity = r.notRespondingReport.tag;
12020            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12021            report.anrInfo.info = r.notRespondingReport.longMsg;
12022        }
12023
12024        return report;
12025    }
12026
12027    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12028        enforceNotIsolatedCaller("getProcessesInErrorState");
12029        // assume our apps are happy - lazy create the list
12030        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12031
12032        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12033                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12034        int userId = UserHandle.getUserId(Binder.getCallingUid());
12035
12036        synchronized (this) {
12037
12038            // iterate across all processes
12039            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12040                ProcessRecord app = mLruProcesses.get(i);
12041                if (!allUsers && app.userId != userId) {
12042                    continue;
12043                }
12044                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12045                    // This one's in trouble, so we'll generate a report for it
12046                    // crashes are higher priority (in case there's a crash *and* an anr)
12047                    ActivityManager.ProcessErrorStateInfo report = null;
12048                    if (app.crashing) {
12049                        report = app.crashingReport;
12050                    } else if (app.notResponding) {
12051                        report = app.notRespondingReport;
12052                    }
12053
12054                    if (report != null) {
12055                        if (errList == null) {
12056                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12057                        }
12058                        errList.add(report);
12059                    } else {
12060                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12061                                " crashing = " + app.crashing +
12062                                " notResponding = " + app.notResponding);
12063                    }
12064                }
12065            }
12066        }
12067
12068        return errList;
12069    }
12070
12071    static int procStateToImportance(int procState, int memAdj,
12072            ActivityManager.RunningAppProcessInfo currApp) {
12073        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12074        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12075            currApp.lru = memAdj;
12076        } else {
12077            currApp.lru = 0;
12078        }
12079        return imp;
12080    }
12081
12082    private void fillInProcMemInfo(ProcessRecord app,
12083            ActivityManager.RunningAppProcessInfo outInfo) {
12084        outInfo.pid = app.pid;
12085        outInfo.uid = app.info.uid;
12086        if (mHeavyWeightProcess == app) {
12087            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12088        }
12089        if (app.persistent) {
12090            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12091        }
12092        if (app.activities.size() > 0) {
12093            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12094        }
12095        outInfo.lastTrimLevel = app.trimMemoryLevel;
12096        int adj = app.curAdj;
12097        int procState = app.curProcState;
12098        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12099        outInfo.importanceReasonCode = app.adjTypeCode;
12100        outInfo.processState = app.curProcState;
12101    }
12102
12103    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12104        enforceNotIsolatedCaller("getRunningAppProcesses");
12105        // Lazy instantiation of list
12106        List<ActivityManager.RunningAppProcessInfo> runList = null;
12107        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12108                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12109        int userId = UserHandle.getUserId(Binder.getCallingUid());
12110        synchronized (this) {
12111            // Iterate across all processes
12112            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12113                ProcessRecord app = mLruProcesses.get(i);
12114                if (!allUsers && app.userId != userId) {
12115                    continue;
12116                }
12117                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12118                    // Generate process state info for running application
12119                    ActivityManager.RunningAppProcessInfo currApp =
12120                        new ActivityManager.RunningAppProcessInfo(app.processName,
12121                                app.pid, app.getPackageList());
12122                    fillInProcMemInfo(app, currApp);
12123                    if (app.adjSource instanceof ProcessRecord) {
12124                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12125                        currApp.importanceReasonImportance =
12126                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12127                                        app.adjSourceProcState);
12128                    } else if (app.adjSource instanceof ActivityRecord) {
12129                        ActivityRecord r = (ActivityRecord)app.adjSource;
12130                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12131                    }
12132                    if (app.adjTarget instanceof ComponentName) {
12133                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12134                    }
12135                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12136                    //        + " lru=" + currApp.lru);
12137                    if (runList == null) {
12138                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12139                    }
12140                    runList.add(currApp);
12141                }
12142            }
12143        }
12144        return runList;
12145    }
12146
12147    public List<ApplicationInfo> getRunningExternalApplications() {
12148        enforceNotIsolatedCaller("getRunningExternalApplications");
12149        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12150        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12151        if (runningApps != null && runningApps.size() > 0) {
12152            Set<String> extList = new HashSet<String>();
12153            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12154                if (app.pkgList != null) {
12155                    for (String pkg : app.pkgList) {
12156                        extList.add(pkg);
12157                    }
12158                }
12159            }
12160            IPackageManager pm = AppGlobals.getPackageManager();
12161            for (String pkg : extList) {
12162                try {
12163                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12164                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12165                        retList.add(info);
12166                    }
12167                } catch (RemoteException e) {
12168                }
12169            }
12170        }
12171        return retList;
12172    }
12173
12174    @Override
12175    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12176        enforceNotIsolatedCaller("getMyMemoryState");
12177        synchronized (this) {
12178            ProcessRecord proc;
12179            synchronized (mPidsSelfLocked) {
12180                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12181            }
12182            fillInProcMemInfo(proc, outInfo);
12183        }
12184    }
12185
12186    @Override
12187    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12188        if (checkCallingPermission(android.Manifest.permission.DUMP)
12189                != PackageManager.PERMISSION_GRANTED) {
12190            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12191                    + Binder.getCallingPid()
12192                    + ", uid=" + Binder.getCallingUid()
12193                    + " without permission "
12194                    + android.Manifest.permission.DUMP);
12195            return;
12196        }
12197
12198        boolean dumpAll = false;
12199        boolean dumpClient = false;
12200        String dumpPackage = null;
12201
12202        int opti = 0;
12203        while (opti < args.length) {
12204            String opt = args[opti];
12205            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12206                break;
12207            }
12208            opti++;
12209            if ("-a".equals(opt)) {
12210                dumpAll = true;
12211            } else if ("-c".equals(opt)) {
12212                dumpClient = true;
12213            } else if ("-h".equals(opt)) {
12214                pw.println("Activity manager dump options:");
12215                pw.println("  [-a] [-c] [-h] [cmd] ...");
12216                pw.println("  cmd may be one of:");
12217                pw.println("    a[ctivities]: activity stack state");
12218                pw.println("    r[recents]: recent activities state");
12219                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12220                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12221                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12222                pw.println("    o[om]: out of memory management");
12223                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12224                pw.println("    provider [COMP_SPEC]: provider client-side state");
12225                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12226                pw.println("    service [COMP_SPEC]: service client-side state");
12227                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12228                pw.println("    all: dump all activities");
12229                pw.println("    top: dump the top activity");
12230                pw.println("    write: write all pending state to storage");
12231                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12232                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12233                pw.println("    a partial substring in a component name, a");
12234                pw.println("    hex object identifier.");
12235                pw.println("  -a: include all available server state.");
12236                pw.println("  -c: include client state.");
12237                return;
12238            } else {
12239                pw.println("Unknown argument: " + opt + "; use -h for help");
12240            }
12241        }
12242
12243        long origId = Binder.clearCallingIdentity();
12244        boolean more = false;
12245        // Is the caller requesting to dump a particular piece of data?
12246        if (opti < args.length) {
12247            String cmd = args[opti];
12248            opti++;
12249            if ("activities".equals(cmd) || "a".equals(cmd)) {
12250                synchronized (this) {
12251                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12252                }
12253            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12254                synchronized (this) {
12255                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12256                }
12257            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12258                String[] newArgs;
12259                String name;
12260                if (opti >= args.length) {
12261                    name = null;
12262                    newArgs = EMPTY_STRING_ARRAY;
12263                } else {
12264                    name = args[opti];
12265                    opti++;
12266                    newArgs = new String[args.length - opti];
12267                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12268                            args.length - opti);
12269                }
12270                synchronized (this) {
12271                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12272                }
12273            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12274                String[] newArgs;
12275                String name;
12276                if (opti >= args.length) {
12277                    name = null;
12278                    newArgs = EMPTY_STRING_ARRAY;
12279                } else {
12280                    name = args[opti];
12281                    opti++;
12282                    newArgs = new String[args.length - opti];
12283                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12284                            args.length - opti);
12285                }
12286                synchronized (this) {
12287                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12288                }
12289            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12290                String[] newArgs;
12291                String name;
12292                if (opti >= args.length) {
12293                    name = null;
12294                    newArgs = EMPTY_STRING_ARRAY;
12295                } else {
12296                    name = args[opti];
12297                    opti++;
12298                    newArgs = new String[args.length - opti];
12299                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12300                            args.length - opti);
12301                }
12302                synchronized (this) {
12303                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12304                }
12305            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12306                synchronized (this) {
12307                    dumpOomLocked(fd, pw, args, opti, true);
12308                }
12309            } else if ("provider".equals(cmd)) {
12310                String[] newArgs;
12311                String name;
12312                if (opti >= args.length) {
12313                    name = null;
12314                    newArgs = EMPTY_STRING_ARRAY;
12315                } else {
12316                    name = args[opti];
12317                    opti++;
12318                    newArgs = new String[args.length - opti];
12319                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12320                }
12321                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12322                    pw.println("No providers match: " + name);
12323                    pw.println("Use -h for help.");
12324                }
12325            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12326                synchronized (this) {
12327                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12328                }
12329            } else if ("service".equals(cmd)) {
12330                String[] newArgs;
12331                String name;
12332                if (opti >= args.length) {
12333                    name = null;
12334                    newArgs = EMPTY_STRING_ARRAY;
12335                } else {
12336                    name = args[opti];
12337                    opti++;
12338                    newArgs = new String[args.length - opti];
12339                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12340                            args.length - opti);
12341                }
12342                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12343                    pw.println("No services match: " + name);
12344                    pw.println("Use -h for help.");
12345                }
12346            } else if ("package".equals(cmd)) {
12347                String[] newArgs;
12348                if (opti >= args.length) {
12349                    pw.println("package: no package name specified");
12350                    pw.println("Use -h for help.");
12351                } else {
12352                    dumpPackage = args[opti];
12353                    opti++;
12354                    newArgs = new String[args.length - opti];
12355                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12356                            args.length - opti);
12357                    args = newArgs;
12358                    opti = 0;
12359                    more = true;
12360                }
12361            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12362                synchronized (this) {
12363                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12364                }
12365            } else if ("write".equals(cmd)) {
12366                mTaskPersister.flush();
12367                pw.println("All tasks persisted.");
12368                return;
12369            } else {
12370                // Dumping a single activity?
12371                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12372                    pw.println("Bad activity command, or no activities match: " + cmd);
12373                    pw.println("Use -h for help.");
12374                }
12375            }
12376            if (!more) {
12377                Binder.restoreCallingIdentity(origId);
12378                return;
12379            }
12380        }
12381
12382        // No piece of data specified, dump everything.
12383        synchronized (this) {
12384            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12385            pw.println();
12386            if (dumpAll) {
12387                pw.println("-------------------------------------------------------------------------------");
12388            }
12389            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12390            pw.println();
12391            if (dumpAll) {
12392                pw.println("-------------------------------------------------------------------------------");
12393            }
12394            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12395            pw.println();
12396            if (dumpAll) {
12397                pw.println("-------------------------------------------------------------------------------");
12398            }
12399            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12400            pw.println();
12401            if (dumpAll) {
12402                pw.println("-------------------------------------------------------------------------------");
12403            }
12404            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12405            pw.println();
12406            if (dumpAll) {
12407                pw.println("-------------------------------------------------------------------------------");
12408            }
12409            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12410            pw.println();
12411            if (dumpAll) {
12412                pw.println("-------------------------------------------------------------------------------");
12413            }
12414            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12415        }
12416        Binder.restoreCallingIdentity(origId);
12417    }
12418
12419    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12420            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12421        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12422
12423        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12424                dumpPackage);
12425        boolean needSep = printedAnything;
12426
12427        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12428                dumpPackage, needSep, "  mFocusedActivity: ");
12429        if (printed) {
12430            printedAnything = true;
12431            needSep = false;
12432        }
12433
12434        if (dumpPackage == null) {
12435            if (needSep) {
12436                pw.println();
12437            }
12438            needSep = true;
12439            printedAnything = true;
12440            mStackSupervisor.dump(pw, "  ");
12441        }
12442
12443        if (!printedAnything) {
12444            pw.println("  (nothing)");
12445        }
12446    }
12447
12448    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12449            int opti, boolean dumpAll, String dumpPackage) {
12450        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12451
12452        boolean printedAnything = false;
12453
12454        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12455            boolean printedHeader = false;
12456
12457            final int N = mRecentTasks.size();
12458            for (int i=0; i<N; i++) {
12459                TaskRecord tr = mRecentTasks.get(i);
12460                if (dumpPackage != null) {
12461                    if (tr.realActivity == null ||
12462                            !dumpPackage.equals(tr.realActivity)) {
12463                        continue;
12464                    }
12465                }
12466                if (!printedHeader) {
12467                    pw.println("  Recent tasks:");
12468                    printedHeader = true;
12469                    printedAnything = true;
12470                }
12471                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12472                        pw.println(tr);
12473                if (dumpAll) {
12474                    mRecentTasks.get(i).dump(pw, "    ");
12475                }
12476            }
12477        }
12478
12479        if (!printedAnything) {
12480            pw.println("  (nothing)");
12481        }
12482    }
12483
12484    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12485            int opti, boolean dumpAll, String dumpPackage) {
12486        boolean needSep = false;
12487        boolean printedAnything = false;
12488        int numPers = 0;
12489
12490        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12491
12492        if (dumpAll) {
12493            final int NP = mProcessNames.getMap().size();
12494            for (int ip=0; ip<NP; ip++) {
12495                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12496                final int NA = procs.size();
12497                for (int ia=0; ia<NA; ia++) {
12498                    ProcessRecord r = procs.valueAt(ia);
12499                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12500                        continue;
12501                    }
12502                    if (!needSep) {
12503                        pw.println("  All known processes:");
12504                        needSep = true;
12505                        printedAnything = true;
12506                    }
12507                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12508                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12509                        pw.print(" "); pw.println(r);
12510                    r.dump(pw, "    ");
12511                    if (r.persistent) {
12512                        numPers++;
12513                    }
12514                }
12515            }
12516        }
12517
12518        if (mIsolatedProcesses.size() > 0) {
12519            boolean printed = false;
12520            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12521                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12522                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12523                    continue;
12524                }
12525                if (!printed) {
12526                    if (needSep) {
12527                        pw.println();
12528                    }
12529                    pw.println("  Isolated process list (sorted by uid):");
12530                    printedAnything = true;
12531                    printed = true;
12532                    needSep = true;
12533                }
12534                pw.println(String.format("%sIsolated #%2d: %s",
12535                        "    ", i, r.toString()));
12536            }
12537        }
12538
12539        if (mLruProcesses.size() > 0) {
12540            if (needSep) {
12541                pw.println();
12542            }
12543            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12544                    pw.print(" total, non-act at ");
12545                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12546                    pw.print(", non-svc at ");
12547                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12548                    pw.println("):");
12549            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12550            needSep = true;
12551            printedAnything = true;
12552        }
12553
12554        if (dumpAll || dumpPackage != null) {
12555            synchronized (mPidsSelfLocked) {
12556                boolean printed = false;
12557                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12558                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12559                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12560                        continue;
12561                    }
12562                    if (!printed) {
12563                        if (needSep) pw.println();
12564                        needSep = true;
12565                        pw.println("  PID mappings:");
12566                        printed = true;
12567                        printedAnything = true;
12568                    }
12569                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12570                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12571                }
12572            }
12573        }
12574
12575        if (mForegroundProcesses.size() > 0) {
12576            synchronized (mPidsSelfLocked) {
12577                boolean printed = false;
12578                for (int i=0; i<mForegroundProcesses.size(); i++) {
12579                    ProcessRecord r = mPidsSelfLocked.get(
12580                            mForegroundProcesses.valueAt(i).pid);
12581                    if (dumpPackage != null && (r == null
12582                            || !r.pkgList.containsKey(dumpPackage))) {
12583                        continue;
12584                    }
12585                    if (!printed) {
12586                        if (needSep) pw.println();
12587                        needSep = true;
12588                        pw.println("  Foreground Processes:");
12589                        printed = true;
12590                        printedAnything = true;
12591                    }
12592                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12593                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12594                }
12595            }
12596        }
12597
12598        if (mPersistentStartingProcesses.size() > 0) {
12599            if (needSep) pw.println();
12600            needSep = true;
12601            printedAnything = true;
12602            pw.println("  Persisent processes that are starting:");
12603            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12604                    "Starting Norm", "Restarting PERS", dumpPackage);
12605        }
12606
12607        if (mRemovedProcesses.size() > 0) {
12608            if (needSep) pw.println();
12609            needSep = true;
12610            printedAnything = true;
12611            pw.println("  Processes that are being removed:");
12612            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12613                    "Removed Norm", "Removed PERS", dumpPackage);
12614        }
12615
12616        if (mProcessesOnHold.size() > 0) {
12617            if (needSep) pw.println();
12618            needSep = true;
12619            printedAnything = true;
12620            pw.println("  Processes that are on old until the system is ready:");
12621            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12622                    "OnHold Norm", "OnHold PERS", dumpPackage);
12623        }
12624
12625        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12626
12627        if (mProcessCrashTimes.getMap().size() > 0) {
12628            boolean printed = false;
12629            long now = SystemClock.uptimeMillis();
12630            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12631            final int NP = pmap.size();
12632            for (int ip=0; ip<NP; ip++) {
12633                String pname = pmap.keyAt(ip);
12634                SparseArray<Long> uids = pmap.valueAt(ip);
12635                final int N = uids.size();
12636                for (int i=0; i<N; i++) {
12637                    int puid = uids.keyAt(i);
12638                    ProcessRecord r = mProcessNames.get(pname, puid);
12639                    if (dumpPackage != null && (r == null
12640                            || !r.pkgList.containsKey(dumpPackage))) {
12641                        continue;
12642                    }
12643                    if (!printed) {
12644                        if (needSep) pw.println();
12645                        needSep = true;
12646                        pw.println("  Time since processes crashed:");
12647                        printed = true;
12648                        printedAnything = true;
12649                    }
12650                    pw.print("    Process "); pw.print(pname);
12651                            pw.print(" uid "); pw.print(puid);
12652                            pw.print(": last crashed ");
12653                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12654                            pw.println(" ago");
12655                }
12656            }
12657        }
12658
12659        if (mBadProcesses.getMap().size() > 0) {
12660            boolean printed = false;
12661            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12662            final int NP = pmap.size();
12663            for (int ip=0; ip<NP; ip++) {
12664                String pname = pmap.keyAt(ip);
12665                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12666                final int N = uids.size();
12667                for (int i=0; i<N; i++) {
12668                    int puid = uids.keyAt(i);
12669                    ProcessRecord r = mProcessNames.get(pname, puid);
12670                    if (dumpPackage != null && (r == null
12671                            || !r.pkgList.containsKey(dumpPackage))) {
12672                        continue;
12673                    }
12674                    if (!printed) {
12675                        if (needSep) pw.println();
12676                        needSep = true;
12677                        pw.println("  Bad processes:");
12678                        printedAnything = true;
12679                    }
12680                    BadProcessInfo info = uids.valueAt(i);
12681                    pw.print("    Bad process "); pw.print(pname);
12682                            pw.print(" uid "); pw.print(puid);
12683                            pw.print(": crashed at time "); pw.println(info.time);
12684                    if (info.shortMsg != null) {
12685                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12686                    }
12687                    if (info.longMsg != null) {
12688                        pw.print("      Long msg: "); pw.println(info.longMsg);
12689                    }
12690                    if (info.stack != null) {
12691                        pw.println("      Stack:");
12692                        int lastPos = 0;
12693                        for (int pos=0; pos<info.stack.length(); pos++) {
12694                            if (info.stack.charAt(pos) == '\n') {
12695                                pw.print("        ");
12696                                pw.write(info.stack, lastPos, pos-lastPos);
12697                                pw.println();
12698                                lastPos = pos+1;
12699                            }
12700                        }
12701                        if (lastPos < info.stack.length()) {
12702                            pw.print("        ");
12703                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12704                            pw.println();
12705                        }
12706                    }
12707                }
12708            }
12709        }
12710
12711        if (dumpPackage == null) {
12712            pw.println();
12713            needSep = false;
12714            pw.println("  mStartedUsers:");
12715            for (int i=0; i<mStartedUsers.size(); i++) {
12716                UserStartedState uss = mStartedUsers.valueAt(i);
12717                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12718                        pw.print(": "); uss.dump("", pw);
12719            }
12720            pw.print("  mStartedUserArray: [");
12721            for (int i=0; i<mStartedUserArray.length; i++) {
12722                if (i > 0) pw.print(", ");
12723                pw.print(mStartedUserArray[i]);
12724            }
12725            pw.println("]");
12726            pw.print("  mUserLru: [");
12727            for (int i=0; i<mUserLru.size(); i++) {
12728                if (i > 0) pw.print(", ");
12729                pw.print(mUserLru.get(i));
12730            }
12731            pw.println("]");
12732            if (dumpAll) {
12733                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12734            }
12735            synchronized (mUserProfileGroupIdsSelfLocked) {
12736                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12737                    pw.println("  mUserProfileGroupIds:");
12738                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12739                        pw.print("    User #");
12740                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12741                        pw.print(" -> profile #");
12742                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12743                    }
12744                }
12745            }
12746        }
12747        if (mHomeProcess != null && (dumpPackage == null
12748                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12749            if (needSep) {
12750                pw.println();
12751                needSep = false;
12752            }
12753            pw.println("  mHomeProcess: " + mHomeProcess);
12754        }
12755        if (mPreviousProcess != null && (dumpPackage == null
12756                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12757            if (needSep) {
12758                pw.println();
12759                needSep = false;
12760            }
12761            pw.println("  mPreviousProcess: " + mPreviousProcess);
12762        }
12763        if (dumpAll) {
12764            StringBuilder sb = new StringBuilder(128);
12765            sb.append("  mPreviousProcessVisibleTime: ");
12766            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12767            pw.println(sb);
12768        }
12769        if (mHeavyWeightProcess != null && (dumpPackage == null
12770                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12771            if (needSep) {
12772                pw.println();
12773                needSep = false;
12774            }
12775            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12776        }
12777        if (dumpPackage == null) {
12778            pw.println("  mConfiguration: " + mConfiguration);
12779        }
12780        if (dumpAll) {
12781            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12782            if (mCompatModePackages.getPackages().size() > 0) {
12783                boolean printed = false;
12784                for (Map.Entry<String, Integer> entry
12785                        : mCompatModePackages.getPackages().entrySet()) {
12786                    String pkg = entry.getKey();
12787                    int mode = entry.getValue();
12788                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12789                        continue;
12790                    }
12791                    if (!printed) {
12792                        pw.println("  mScreenCompatPackages:");
12793                        printed = true;
12794                    }
12795                    pw.print("    "); pw.print(pkg); pw.print(": ");
12796                            pw.print(mode); pw.println();
12797                }
12798            }
12799        }
12800        if (dumpPackage == null) {
12801            if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) {
12802                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12803                        + " mLockScreenShown " + lockScreenShownToString());
12804            }
12805            if (mShuttingDown || mRunningVoice) {
12806                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12807            }
12808        }
12809        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12810                || mOrigWaitForDebugger) {
12811            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12812                    || dumpPackage.equals(mOrigDebugApp)) {
12813                if (needSep) {
12814                    pw.println();
12815                    needSep = false;
12816                }
12817                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12818                        + " mDebugTransient=" + mDebugTransient
12819                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12820            }
12821        }
12822        if (mOpenGlTraceApp != null) {
12823            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12824                if (needSep) {
12825                    pw.println();
12826                    needSep = false;
12827                }
12828                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12829            }
12830        }
12831        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12832                || mProfileFd != null) {
12833            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12834                if (needSep) {
12835                    pw.println();
12836                    needSep = false;
12837                }
12838                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12839                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12840                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12841                        + mAutoStopProfiler);
12842                pw.println("  mProfileType=" + mProfileType);
12843            }
12844        }
12845        if (dumpPackage == null) {
12846            if (mAlwaysFinishActivities || mController != null) {
12847                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12848                        + " mController=" + mController);
12849            }
12850            if (dumpAll) {
12851                pw.println("  Total persistent processes: " + numPers);
12852                pw.println("  mProcessesReady=" + mProcessesReady
12853                        + " mSystemReady=" + mSystemReady
12854                        + " mBooted=" + mBooted
12855                        + " mFactoryTest=" + mFactoryTest);
12856                pw.println("  mBooting=" + mBooting
12857                        + " mCallFinishBooting=" + mCallFinishBooting
12858                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12859                pw.print("  mLastPowerCheckRealtime=");
12860                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12861                        pw.println("");
12862                pw.print("  mLastPowerCheckUptime=");
12863                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12864                        pw.println("");
12865                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12866                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12867                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12868                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12869                        + " (" + mLruProcesses.size() + " total)"
12870                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12871                        + " mNumServiceProcs=" + mNumServiceProcs
12872                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12873                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12874                        + " mLastMemoryLevel" + mLastMemoryLevel
12875                        + " mLastNumProcesses" + mLastNumProcesses);
12876                long now = SystemClock.uptimeMillis();
12877                pw.print("  mLastIdleTime=");
12878                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12879                        pw.print(" mLowRamSinceLastIdle=");
12880                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12881                        pw.println();
12882            }
12883        }
12884
12885        if (!printedAnything) {
12886            pw.println("  (nothing)");
12887        }
12888    }
12889
12890    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12891            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12892        if (mProcessesToGc.size() > 0) {
12893            boolean printed = false;
12894            long now = SystemClock.uptimeMillis();
12895            for (int i=0; i<mProcessesToGc.size(); i++) {
12896                ProcessRecord proc = mProcessesToGc.get(i);
12897                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12898                    continue;
12899                }
12900                if (!printed) {
12901                    if (needSep) pw.println();
12902                    needSep = true;
12903                    pw.println("  Processes that are waiting to GC:");
12904                    printed = true;
12905                }
12906                pw.print("    Process "); pw.println(proc);
12907                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12908                        pw.print(", last gced=");
12909                        pw.print(now-proc.lastRequestedGc);
12910                        pw.print(" ms ago, last lowMem=");
12911                        pw.print(now-proc.lastLowMemory);
12912                        pw.println(" ms ago");
12913
12914            }
12915        }
12916        return needSep;
12917    }
12918
12919    void printOomLevel(PrintWriter pw, String name, int adj) {
12920        pw.print("    ");
12921        if (adj >= 0) {
12922            pw.print(' ');
12923            if (adj < 10) pw.print(' ');
12924        } else {
12925            if (adj > -10) pw.print(' ');
12926        }
12927        pw.print(adj);
12928        pw.print(": ");
12929        pw.print(name);
12930        pw.print(" (");
12931        pw.print(mProcessList.getMemLevel(adj)/1024);
12932        pw.println(" kB)");
12933    }
12934
12935    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12936            int opti, boolean dumpAll) {
12937        boolean needSep = false;
12938
12939        if (mLruProcesses.size() > 0) {
12940            if (needSep) pw.println();
12941            needSep = true;
12942            pw.println("  OOM levels:");
12943            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12944            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12945            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12946            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12947            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12948            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12949            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12950            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12951            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12952            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12953            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12954            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12955            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12956            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12957
12958            if (needSep) pw.println();
12959            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12960                    pw.print(" total, non-act at ");
12961                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12962                    pw.print(", non-svc at ");
12963                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12964                    pw.println("):");
12965            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12966            needSep = true;
12967        }
12968
12969        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12970
12971        pw.println();
12972        pw.println("  mHomeProcess: " + mHomeProcess);
12973        pw.println("  mPreviousProcess: " + mPreviousProcess);
12974        if (mHeavyWeightProcess != null) {
12975            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12976        }
12977
12978        return true;
12979    }
12980
12981    /**
12982     * There are three ways to call this:
12983     *  - no provider specified: dump all the providers
12984     *  - a flattened component name that matched an existing provider was specified as the
12985     *    first arg: dump that one provider
12986     *  - the first arg isn't the flattened component name of an existing provider:
12987     *    dump all providers whose component contains the first arg as a substring
12988     */
12989    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12990            int opti, boolean dumpAll) {
12991        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12992    }
12993
12994    static class ItemMatcher {
12995        ArrayList<ComponentName> components;
12996        ArrayList<String> strings;
12997        ArrayList<Integer> objects;
12998        boolean all;
12999
13000        ItemMatcher() {
13001            all = true;
13002        }
13003
13004        void build(String name) {
13005            ComponentName componentName = ComponentName.unflattenFromString(name);
13006            if (componentName != null) {
13007                if (components == null) {
13008                    components = new ArrayList<ComponentName>();
13009                }
13010                components.add(componentName);
13011                all = false;
13012            } else {
13013                int objectId = 0;
13014                // Not a '/' separated full component name; maybe an object ID?
13015                try {
13016                    objectId = Integer.parseInt(name, 16);
13017                    if (objects == null) {
13018                        objects = new ArrayList<Integer>();
13019                    }
13020                    objects.add(objectId);
13021                    all = false;
13022                } catch (RuntimeException e) {
13023                    // Not an integer; just do string match.
13024                    if (strings == null) {
13025                        strings = new ArrayList<String>();
13026                    }
13027                    strings.add(name);
13028                    all = false;
13029                }
13030            }
13031        }
13032
13033        int build(String[] args, int opti) {
13034            for (; opti<args.length; opti++) {
13035                String name = args[opti];
13036                if ("--".equals(name)) {
13037                    return opti+1;
13038                }
13039                build(name);
13040            }
13041            return opti;
13042        }
13043
13044        boolean match(Object object, ComponentName comp) {
13045            if (all) {
13046                return true;
13047            }
13048            if (components != null) {
13049                for (int i=0; i<components.size(); i++) {
13050                    if (components.get(i).equals(comp)) {
13051                        return true;
13052                    }
13053                }
13054            }
13055            if (objects != null) {
13056                for (int i=0; i<objects.size(); i++) {
13057                    if (System.identityHashCode(object) == objects.get(i)) {
13058                        return true;
13059                    }
13060                }
13061            }
13062            if (strings != null) {
13063                String flat = comp.flattenToString();
13064                for (int i=0; i<strings.size(); i++) {
13065                    if (flat.contains(strings.get(i))) {
13066                        return true;
13067                    }
13068                }
13069            }
13070            return false;
13071        }
13072    }
13073
13074    /**
13075     * There are three things that cmd can be:
13076     *  - a flattened component name that matches an existing activity
13077     *  - the cmd arg isn't the flattened component name of an existing activity:
13078     *    dump all activity whose component contains the cmd as a substring
13079     *  - A hex number of the ActivityRecord object instance.
13080     */
13081    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13082            int opti, boolean dumpAll) {
13083        ArrayList<ActivityRecord> activities;
13084
13085        synchronized (this) {
13086            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13087        }
13088
13089        if (activities.size() <= 0) {
13090            return false;
13091        }
13092
13093        String[] newArgs = new String[args.length - opti];
13094        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13095
13096        TaskRecord lastTask = null;
13097        boolean needSep = false;
13098        for (int i=activities.size()-1; i>=0; i--) {
13099            ActivityRecord r = activities.get(i);
13100            if (needSep) {
13101                pw.println();
13102            }
13103            needSep = true;
13104            synchronized (this) {
13105                if (lastTask != r.task) {
13106                    lastTask = r.task;
13107                    pw.print("TASK "); pw.print(lastTask.affinity);
13108                            pw.print(" id="); pw.println(lastTask.taskId);
13109                    if (dumpAll) {
13110                        lastTask.dump(pw, "  ");
13111                    }
13112                }
13113            }
13114            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13115        }
13116        return true;
13117    }
13118
13119    /**
13120     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13121     * there is a thread associated with the activity.
13122     */
13123    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13124            final ActivityRecord r, String[] args, boolean dumpAll) {
13125        String innerPrefix = prefix + "  ";
13126        synchronized (this) {
13127            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13128                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13129                    pw.print(" pid=");
13130                    if (r.app != null) pw.println(r.app.pid);
13131                    else pw.println("(not running)");
13132            if (dumpAll) {
13133                r.dump(pw, innerPrefix);
13134            }
13135        }
13136        if (r.app != null && r.app.thread != null) {
13137            // flush anything that is already in the PrintWriter since the thread is going
13138            // to write to the file descriptor directly
13139            pw.flush();
13140            try {
13141                TransferPipe tp = new TransferPipe();
13142                try {
13143                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13144                            r.appToken, innerPrefix, args);
13145                    tp.go(fd);
13146                } finally {
13147                    tp.kill();
13148                }
13149            } catch (IOException e) {
13150                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13151            } catch (RemoteException e) {
13152                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13153            }
13154        }
13155    }
13156
13157    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13158            int opti, boolean dumpAll, String dumpPackage) {
13159        boolean needSep = false;
13160        boolean onlyHistory = false;
13161        boolean printedAnything = false;
13162
13163        if ("history".equals(dumpPackage)) {
13164            if (opti < args.length && "-s".equals(args[opti])) {
13165                dumpAll = false;
13166            }
13167            onlyHistory = true;
13168            dumpPackage = null;
13169        }
13170
13171        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13172        if (!onlyHistory && dumpAll) {
13173            if (mRegisteredReceivers.size() > 0) {
13174                boolean printed = false;
13175                Iterator it = mRegisteredReceivers.values().iterator();
13176                while (it.hasNext()) {
13177                    ReceiverList r = (ReceiverList)it.next();
13178                    if (dumpPackage != null && (r.app == null ||
13179                            !dumpPackage.equals(r.app.info.packageName))) {
13180                        continue;
13181                    }
13182                    if (!printed) {
13183                        pw.println("  Registered Receivers:");
13184                        needSep = true;
13185                        printed = true;
13186                        printedAnything = true;
13187                    }
13188                    pw.print("  * "); pw.println(r);
13189                    r.dump(pw, "    ");
13190                }
13191            }
13192
13193            if (mReceiverResolver.dump(pw, needSep ?
13194                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13195                    "    ", dumpPackage, false)) {
13196                needSep = true;
13197                printedAnything = true;
13198            }
13199        }
13200
13201        for (BroadcastQueue q : mBroadcastQueues) {
13202            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13203            printedAnything |= needSep;
13204        }
13205
13206        needSep = true;
13207
13208        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13209            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13210                if (needSep) {
13211                    pw.println();
13212                }
13213                needSep = true;
13214                printedAnything = true;
13215                pw.print("  Sticky broadcasts for user ");
13216                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13217                StringBuilder sb = new StringBuilder(128);
13218                for (Map.Entry<String, ArrayList<Intent>> ent
13219                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13220                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13221                    if (dumpAll) {
13222                        pw.println(":");
13223                        ArrayList<Intent> intents = ent.getValue();
13224                        final int N = intents.size();
13225                        for (int i=0; i<N; i++) {
13226                            sb.setLength(0);
13227                            sb.append("    Intent: ");
13228                            intents.get(i).toShortString(sb, false, true, false, false);
13229                            pw.println(sb.toString());
13230                            Bundle bundle = intents.get(i).getExtras();
13231                            if (bundle != null) {
13232                                pw.print("      ");
13233                                pw.println(bundle.toString());
13234                            }
13235                        }
13236                    } else {
13237                        pw.println("");
13238                    }
13239                }
13240            }
13241        }
13242
13243        if (!onlyHistory && dumpAll) {
13244            pw.println();
13245            for (BroadcastQueue queue : mBroadcastQueues) {
13246                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13247                        + queue.mBroadcastsScheduled);
13248            }
13249            pw.println("  mHandler:");
13250            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13251            needSep = true;
13252            printedAnything = true;
13253        }
13254
13255        if (!printedAnything) {
13256            pw.println("  (nothing)");
13257        }
13258    }
13259
13260    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13261            int opti, boolean dumpAll, String dumpPackage) {
13262        boolean needSep;
13263        boolean printedAnything = false;
13264
13265        ItemMatcher matcher = new ItemMatcher();
13266        matcher.build(args, opti);
13267
13268        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13269
13270        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13271        printedAnything |= needSep;
13272
13273        if (mLaunchingProviders.size() > 0) {
13274            boolean printed = false;
13275            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13276                ContentProviderRecord r = mLaunchingProviders.get(i);
13277                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13278                    continue;
13279                }
13280                if (!printed) {
13281                    if (needSep) pw.println();
13282                    needSep = true;
13283                    pw.println("  Launching content providers:");
13284                    printed = true;
13285                    printedAnything = true;
13286                }
13287                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13288                        pw.println(r);
13289            }
13290        }
13291
13292        if (mGrantedUriPermissions.size() > 0) {
13293            boolean printed = false;
13294            int dumpUid = -2;
13295            if (dumpPackage != null) {
13296                try {
13297                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13298                } catch (NameNotFoundException e) {
13299                    dumpUid = -1;
13300                }
13301            }
13302            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13303                int uid = mGrantedUriPermissions.keyAt(i);
13304                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13305                    continue;
13306                }
13307                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13308                if (!printed) {
13309                    if (needSep) pw.println();
13310                    needSep = true;
13311                    pw.println("  Granted Uri Permissions:");
13312                    printed = true;
13313                    printedAnything = true;
13314                }
13315                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13316                for (UriPermission perm : perms.values()) {
13317                    pw.print("    "); pw.println(perm);
13318                    if (dumpAll) {
13319                        perm.dump(pw, "      ");
13320                    }
13321                }
13322            }
13323        }
13324
13325        if (!printedAnything) {
13326            pw.println("  (nothing)");
13327        }
13328    }
13329
13330    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13331            int opti, boolean dumpAll, String dumpPackage) {
13332        boolean printed = false;
13333
13334        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13335
13336        if (mIntentSenderRecords.size() > 0) {
13337            Iterator<WeakReference<PendingIntentRecord>> it
13338                    = mIntentSenderRecords.values().iterator();
13339            while (it.hasNext()) {
13340                WeakReference<PendingIntentRecord> ref = it.next();
13341                PendingIntentRecord rec = ref != null ? ref.get(): null;
13342                if (dumpPackage != null && (rec == null
13343                        || !dumpPackage.equals(rec.key.packageName))) {
13344                    continue;
13345                }
13346                printed = true;
13347                if (rec != null) {
13348                    pw.print("  * "); pw.println(rec);
13349                    if (dumpAll) {
13350                        rec.dump(pw, "    ");
13351                    }
13352                } else {
13353                    pw.print("  * "); pw.println(ref);
13354                }
13355            }
13356        }
13357
13358        if (!printed) {
13359            pw.println("  (nothing)");
13360        }
13361    }
13362
13363    private static final int dumpProcessList(PrintWriter pw,
13364            ActivityManagerService service, List list,
13365            String prefix, String normalLabel, String persistentLabel,
13366            String dumpPackage) {
13367        int numPers = 0;
13368        final int N = list.size()-1;
13369        for (int i=N; i>=0; i--) {
13370            ProcessRecord r = (ProcessRecord)list.get(i);
13371            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13372                continue;
13373            }
13374            pw.println(String.format("%s%s #%2d: %s",
13375                    prefix, (r.persistent ? persistentLabel : normalLabel),
13376                    i, r.toString()));
13377            if (r.persistent) {
13378                numPers++;
13379            }
13380        }
13381        return numPers;
13382    }
13383
13384    private static final boolean dumpProcessOomList(PrintWriter pw,
13385            ActivityManagerService service, List<ProcessRecord> origList,
13386            String prefix, String normalLabel, String persistentLabel,
13387            boolean inclDetails, String dumpPackage) {
13388
13389        ArrayList<Pair<ProcessRecord, Integer>> list
13390                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13391        for (int i=0; i<origList.size(); i++) {
13392            ProcessRecord r = origList.get(i);
13393            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13394                continue;
13395            }
13396            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13397        }
13398
13399        if (list.size() <= 0) {
13400            return false;
13401        }
13402
13403        Comparator<Pair<ProcessRecord, Integer>> comparator
13404                = new Comparator<Pair<ProcessRecord, Integer>>() {
13405            @Override
13406            public int compare(Pair<ProcessRecord, Integer> object1,
13407                    Pair<ProcessRecord, Integer> object2) {
13408                if (object1.first.setAdj != object2.first.setAdj) {
13409                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13410                }
13411                if (object1.second.intValue() != object2.second.intValue()) {
13412                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13413                }
13414                return 0;
13415            }
13416        };
13417
13418        Collections.sort(list, comparator);
13419
13420        final long curRealtime = SystemClock.elapsedRealtime();
13421        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13422        final long curUptime = SystemClock.uptimeMillis();
13423        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13424
13425        for (int i=list.size()-1; i>=0; i--) {
13426            ProcessRecord r = list.get(i).first;
13427            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13428            char schedGroup;
13429            switch (r.setSchedGroup) {
13430                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13431                    schedGroup = 'B';
13432                    break;
13433                case Process.THREAD_GROUP_DEFAULT:
13434                    schedGroup = 'F';
13435                    break;
13436                default:
13437                    schedGroup = '?';
13438                    break;
13439            }
13440            char foreground;
13441            if (r.foregroundActivities) {
13442                foreground = 'A';
13443            } else if (r.foregroundServices) {
13444                foreground = 'S';
13445            } else {
13446                foreground = ' ';
13447            }
13448            String procState = ProcessList.makeProcStateString(r.curProcState);
13449            pw.print(prefix);
13450            pw.print(r.persistent ? persistentLabel : normalLabel);
13451            pw.print(" #");
13452            int num = (origList.size()-1)-list.get(i).second;
13453            if (num < 10) pw.print(' ');
13454            pw.print(num);
13455            pw.print(": ");
13456            pw.print(oomAdj);
13457            pw.print(' ');
13458            pw.print(schedGroup);
13459            pw.print('/');
13460            pw.print(foreground);
13461            pw.print('/');
13462            pw.print(procState);
13463            pw.print(" trm:");
13464            if (r.trimMemoryLevel < 10) pw.print(' ');
13465            pw.print(r.trimMemoryLevel);
13466            pw.print(' ');
13467            pw.print(r.toShortString());
13468            pw.print(" (");
13469            pw.print(r.adjType);
13470            pw.println(')');
13471            if (r.adjSource != null || r.adjTarget != null) {
13472                pw.print(prefix);
13473                pw.print("    ");
13474                if (r.adjTarget instanceof ComponentName) {
13475                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13476                } else if (r.adjTarget != null) {
13477                    pw.print(r.adjTarget.toString());
13478                } else {
13479                    pw.print("{null}");
13480                }
13481                pw.print("<=");
13482                if (r.adjSource instanceof ProcessRecord) {
13483                    pw.print("Proc{");
13484                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13485                    pw.println("}");
13486                } else if (r.adjSource != null) {
13487                    pw.println(r.adjSource.toString());
13488                } else {
13489                    pw.println("{null}");
13490                }
13491            }
13492            if (inclDetails) {
13493                pw.print(prefix);
13494                pw.print("    ");
13495                pw.print("oom: max="); pw.print(r.maxAdj);
13496                pw.print(" curRaw="); pw.print(r.curRawAdj);
13497                pw.print(" setRaw="); pw.print(r.setRawAdj);
13498                pw.print(" cur="); pw.print(r.curAdj);
13499                pw.print(" set="); pw.println(r.setAdj);
13500                pw.print(prefix);
13501                pw.print("    ");
13502                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13503                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13504                pw.print(" lastPss="); pw.print(r.lastPss);
13505                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13506                pw.print(prefix);
13507                pw.print("    ");
13508                pw.print("cached="); pw.print(r.cached);
13509                pw.print(" empty="); pw.print(r.empty);
13510                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13511
13512                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13513                    if (r.lastWakeTime != 0) {
13514                        long wtime;
13515                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13516                        synchronized (stats) {
13517                            wtime = stats.getProcessWakeTime(r.info.uid,
13518                                    r.pid, curRealtime);
13519                        }
13520                        long timeUsed = wtime - r.lastWakeTime;
13521                        pw.print(prefix);
13522                        pw.print("    ");
13523                        pw.print("keep awake over ");
13524                        TimeUtils.formatDuration(realtimeSince, pw);
13525                        pw.print(" used ");
13526                        TimeUtils.formatDuration(timeUsed, pw);
13527                        pw.print(" (");
13528                        pw.print((timeUsed*100)/realtimeSince);
13529                        pw.println("%)");
13530                    }
13531                    if (r.lastCpuTime != 0) {
13532                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13533                        pw.print(prefix);
13534                        pw.print("    ");
13535                        pw.print("run cpu over ");
13536                        TimeUtils.formatDuration(uptimeSince, pw);
13537                        pw.print(" used ");
13538                        TimeUtils.formatDuration(timeUsed, pw);
13539                        pw.print(" (");
13540                        pw.print((timeUsed*100)/uptimeSince);
13541                        pw.println("%)");
13542                    }
13543                }
13544            }
13545        }
13546        return true;
13547    }
13548
13549    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13550            String[] args) {
13551        ArrayList<ProcessRecord> procs;
13552        synchronized (this) {
13553            if (args != null && args.length > start
13554                    && args[start].charAt(0) != '-') {
13555                procs = new ArrayList<ProcessRecord>();
13556                int pid = -1;
13557                try {
13558                    pid = Integer.parseInt(args[start]);
13559                } catch (NumberFormatException e) {
13560                }
13561                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13562                    ProcessRecord proc = mLruProcesses.get(i);
13563                    if (proc.pid == pid) {
13564                        procs.add(proc);
13565                    } else if (allPkgs && proc.pkgList != null
13566                            && proc.pkgList.containsKey(args[start])) {
13567                        procs.add(proc);
13568                    } else if (proc.processName.equals(args[start])) {
13569                        procs.add(proc);
13570                    }
13571                }
13572                if (procs.size() <= 0) {
13573                    return null;
13574                }
13575            } else {
13576                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13577            }
13578        }
13579        return procs;
13580    }
13581
13582    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13583            PrintWriter pw, String[] args) {
13584        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13585        if (procs == null) {
13586            pw.println("No process found for: " + args[0]);
13587            return;
13588        }
13589
13590        long uptime = SystemClock.uptimeMillis();
13591        long realtime = SystemClock.elapsedRealtime();
13592        pw.println("Applications Graphics Acceleration Info:");
13593        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13594
13595        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13596            ProcessRecord r = procs.get(i);
13597            if (r.thread != null) {
13598                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13599                pw.flush();
13600                try {
13601                    TransferPipe tp = new TransferPipe();
13602                    try {
13603                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13604                        tp.go(fd);
13605                    } finally {
13606                        tp.kill();
13607                    }
13608                } catch (IOException e) {
13609                    pw.println("Failure while dumping the app: " + r);
13610                    pw.flush();
13611                } catch (RemoteException e) {
13612                    pw.println("Got a RemoteException while dumping the app " + r);
13613                    pw.flush();
13614                }
13615            }
13616        }
13617    }
13618
13619    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13620        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13621        if (procs == null) {
13622            pw.println("No process found for: " + args[0]);
13623            return;
13624        }
13625
13626        pw.println("Applications Database Info:");
13627
13628        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13629            ProcessRecord r = procs.get(i);
13630            if (r.thread != null) {
13631                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13632                pw.flush();
13633                try {
13634                    TransferPipe tp = new TransferPipe();
13635                    try {
13636                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13637                        tp.go(fd);
13638                    } finally {
13639                        tp.kill();
13640                    }
13641                } catch (IOException e) {
13642                    pw.println("Failure while dumping the app: " + r);
13643                    pw.flush();
13644                } catch (RemoteException e) {
13645                    pw.println("Got a RemoteException while dumping the app " + r);
13646                    pw.flush();
13647                }
13648            }
13649        }
13650    }
13651
13652    final static class MemItem {
13653        final boolean isProc;
13654        final String label;
13655        final String shortLabel;
13656        final long pss;
13657        final int id;
13658        final boolean hasActivities;
13659        ArrayList<MemItem> subitems;
13660
13661        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13662                boolean _hasActivities) {
13663            isProc = true;
13664            label = _label;
13665            shortLabel = _shortLabel;
13666            pss = _pss;
13667            id = _id;
13668            hasActivities = _hasActivities;
13669        }
13670
13671        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13672            isProc = false;
13673            label = _label;
13674            shortLabel = _shortLabel;
13675            pss = _pss;
13676            id = _id;
13677            hasActivities = false;
13678        }
13679    }
13680
13681    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13682            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13683        if (sort && !isCompact) {
13684            Collections.sort(items, new Comparator<MemItem>() {
13685                @Override
13686                public int compare(MemItem lhs, MemItem rhs) {
13687                    if (lhs.pss < rhs.pss) {
13688                        return 1;
13689                    } else if (lhs.pss > rhs.pss) {
13690                        return -1;
13691                    }
13692                    return 0;
13693                }
13694            });
13695        }
13696
13697        for (int i=0; i<items.size(); i++) {
13698            MemItem mi = items.get(i);
13699            if (!isCompact) {
13700                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13701            } else if (mi.isProc) {
13702                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13703                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13704                pw.println(mi.hasActivities ? ",a" : ",e");
13705            } else {
13706                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13707                pw.println(mi.pss);
13708            }
13709            if (mi.subitems != null) {
13710                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13711                        true, isCompact);
13712            }
13713        }
13714    }
13715
13716    // These are in KB.
13717    static final long[] DUMP_MEM_BUCKETS = new long[] {
13718        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13719        120*1024, 160*1024, 200*1024,
13720        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13721        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13722    };
13723
13724    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13725            boolean stackLike) {
13726        int start = label.lastIndexOf('.');
13727        if (start >= 0) start++;
13728        else start = 0;
13729        int end = label.length();
13730        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13731            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13732                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13733                out.append(bucket);
13734                out.append(stackLike ? "MB." : "MB ");
13735                out.append(label, start, end);
13736                return;
13737            }
13738        }
13739        out.append(memKB/1024);
13740        out.append(stackLike ? "MB." : "MB ");
13741        out.append(label, start, end);
13742    }
13743
13744    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13745            ProcessList.NATIVE_ADJ,
13746            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13747            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13748            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13749            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13750            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13751            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13752    };
13753    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13754            "Native",
13755            "System", "Persistent", "Persistent Service", "Foreground",
13756            "Visible", "Perceptible",
13757            "Heavy Weight", "Backup",
13758            "A Services", "Home",
13759            "Previous", "B Services", "Cached"
13760    };
13761    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13762            "native",
13763            "sys", "pers", "persvc", "fore",
13764            "vis", "percept",
13765            "heavy", "backup",
13766            "servicea", "home",
13767            "prev", "serviceb", "cached"
13768    };
13769
13770    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13771            long realtime, boolean isCheckinRequest, boolean isCompact) {
13772        if (isCheckinRequest || isCompact) {
13773            // short checkin version
13774            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13775        } else {
13776            pw.println("Applications Memory Usage (kB):");
13777            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13778        }
13779    }
13780
13781    private static final int KSM_SHARED = 0;
13782    private static final int KSM_SHARING = 1;
13783    private static final int KSM_UNSHARED = 2;
13784    private static final int KSM_VOLATILE = 3;
13785
13786    private final long[] getKsmInfo() {
13787        long[] longOut = new long[4];
13788        final int[] SINGLE_LONG_FORMAT = new int[] {
13789            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13790        };
13791        long[] longTmp = new long[1];
13792        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13793                SINGLE_LONG_FORMAT, null, longTmp, null);
13794        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13795        longTmp[0] = 0;
13796        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13797                SINGLE_LONG_FORMAT, null, longTmp, null);
13798        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13799        longTmp[0] = 0;
13800        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13801                SINGLE_LONG_FORMAT, null, longTmp, null);
13802        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13803        longTmp[0] = 0;
13804        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13805                SINGLE_LONG_FORMAT, null, longTmp, null);
13806        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13807        return longOut;
13808    }
13809
13810    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13811            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13812        boolean dumpDetails = false;
13813        boolean dumpFullDetails = false;
13814        boolean dumpDalvik = false;
13815        boolean oomOnly = false;
13816        boolean isCompact = false;
13817        boolean localOnly = false;
13818        boolean packages = false;
13819
13820        int opti = 0;
13821        while (opti < args.length) {
13822            String opt = args[opti];
13823            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13824                break;
13825            }
13826            opti++;
13827            if ("-a".equals(opt)) {
13828                dumpDetails = true;
13829                dumpFullDetails = true;
13830                dumpDalvik = true;
13831            } else if ("-d".equals(opt)) {
13832                dumpDalvik = true;
13833            } else if ("-c".equals(opt)) {
13834                isCompact = true;
13835            } else if ("--oom".equals(opt)) {
13836                oomOnly = true;
13837            } else if ("--local".equals(opt)) {
13838                localOnly = true;
13839            } else if ("--package".equals(opt)) {
13840                packages = true;
13841            } else if ("-h".equals(opt)) {
13842                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13843                pw.println("  -a: include all available information for each process.");
13844                pw.println("  -d: include dalvik details when dumping process details.");
13845                pw.println("  -c: dump in a compact machine-parseable representation.");
13846                pw.println("  --oom: only show processes organized by oom adj.");
13847                pw.println("  --local: only collect details locally, don't call process.");
13848                pw.println("  --package: interpret process arg as package, dumping all");
13849                pw.println("             processes that have loaded that package.");
13850                pw.println("If [process] is specified it can be the name or ");
13851                pw.println("pid of a specific process to dump.");
13852                return;
13853            } else {
13854                pw.println("Unknown argument: " + opt + "; use -h for help");
13855            }
13856        }
13857
13858        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13859        long uptime = SystemClock.uptimeMillis();
13860        long realtime = SystemClock.elapsedRealtime();
13861        final long[] tmpLong = new long[1];
13862
13863        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13864        if (procs == null) {
13865            // No Java processes.  Maybe they want to print a native process.
13866            if (args != null && args.length > opti
13867                    && args[opti].charAt(0) != '-') {
13868                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13869                        = new ArrayList<ProcessCpuTracker.Stats>();
13870                updateCpuStatsNow();
13871                int findPid = -1;
13872                try {
13873                    findPid = Integer.parseInt(args[opti]);
13874                } catch (NumberFormatException e) {
13875                }
13876                synchronized (mProcessCpuTracker) {
13877                    final int N = mProcessCpuTracker.countStats();
13878                    for (int i=0; i<N; i++) {
13879                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13880                        if (st.pid == findPid || (st.baseName != null
13881                                && st.baseName.equals(args[opti]))) {
13882                            nativeProcs.add(st);
13883                        }
13884                    }
13885                }
13886                if (nativeProcs.size() > 0) {
13887                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13888                            isCompact);
13889                    Debug.MemoryInfo mi = null;
13890                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13891                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13892                        final int pid = r.pid;
13893                        if (!isCheckinRequest && dumpDetails) {
13894                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13895                        }
13896                        if (mi == null) {
13897                            mi = new Debug.MemoryInfo();
13898                        }
13899                        if (dumpDetails || (!brief && !oomOnly)) {
13900                            Debug.getMemoryInfo(pid, mi);
13901                        } else {
13902                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13903                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13904                        }
13905                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13906                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13907                        if (isCheckinRequest) {
13908                            pw.println();
13909                        }
13910                    }
13911                    return;
13912                }
13913            }
13914            pw.println("No process found for: " + args[opti]);
13915            return;
13916        }
13917
13918        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13919            dumpDetails = true;
13920        }
13921
13922        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13923
13924        String[] innerArgs = new String[args.length-opti];
13925        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13926
13927        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13928        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13929        long nativePss=0, dalvikPss=0, otherPss=0;
13930        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13931
13932        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13933        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13934                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13935
13936        long totalPss = 0;
13937        long cachedPss = 0;
13938
13939        Debug.MemoryInfo mi = null;
13940        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13941            final ProcessRecord r = procs.get(i);
13942            final IApplicationThread thread;
13943            final int pid;
13944            final int oomAdj;
13945            final boolean hasActivities;
13946            synchronized (this) {
13947                thread = r.thread;
13948                pid = r.pid;
13949                oomAdj = r.getSetAdjWithServices();
13950                hasActivities = r.activities.size() > 0;
13951            }
13952            if (thread != null) {
13953                if (!isCheckinRequest && dumpDetails) {
13954                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13955                }
13956                if (mi == null) {
13957                    mi = new Debug.MemoryInfo();
13958                }
13959                if (dumpDetails || (!brief && !oomOnly)) {
13960                    Debug.getMemoryInfo(pid, mi);
13961                } else {
13962                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13963                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13964                }
13965                if (dumpDetails) {
13966                    if (localOnly) {
13967                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13968                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13969                        if (isCheckinRequest) {
13970                            pw.println();
13971                        }
13972                    } else {
13973                        try {
13974                            pw.flush();
13975                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13976                                    dumpDalvik, innerArgs);
13977                        } catch (RemoteException e) {
13978                            if (!isCheckinRequest) {
13979                                pw.println("Got RemoteException!");
13980                                pw.flush();
13981                            }
13982                        }
13983                    }
13984                }
13985
13986                final long myTotalPss = mi.getTotalPss();
13987                final long myTotalUss = mi.getTotalUss();
13988
13989                synchronized (this) {
13990                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13991                        // Record this for posterity if the process has been stable.
13992                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13993                    }
13994                }
13995
13996                if (!isCheckinRequest && mi != null) {
13997                    totalPss += myTotalPss;
13998                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13999                            (hasActivities ? " / activities)" : ")"),
14000                            r.processName, myTotalPss, pid, hasActivities);
14001                    procMems.add(pssItem);
14002                    procMemsMap.put(pid, pssItem);
14003
14004                    nativePss += mi.nativePss;
14005                    dalvikPss += mi.dalvikPss;
14006                    otherPss += mi.otherPss;
14007                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14008                        long mem = mi.getOtherPss(j);
14009                        miscPss[j] += mem;
14010                        otherPss -= mem;
14011                    }
14012
14013                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14014                        cachedPss += myTotalPss;
14015                    }
14016
14017                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14018                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14019                                || oomIndex == (oomPss.length-1)) {
14020                            oomPss[oomIndex] += myTotalPss;
14021                            if (oomProcs[oomIndex] == null) {
14022                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14023                            }
14024                            oomProcs[oomIndex].add(pssItem);
14025                            break;
14026                        }
14027                    }
14028                }
14029            }
14030        }
14031
14032        long nativeProcTotalPss = 0;
14033
14034        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14035            // If we are showing aggregations, also look for native processes to
14036            // include so that our aggregations are more accurate.
14037            updateCpuStatsNow();
14038            synchronized (mProcessCpuTracker) {
14039                final int N = mProcessCpuTracker.countStats();
14040                for (int i=0; i<N; i++) {
14041                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14042                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14043                        if (mi == null) {
14044                            mi = new Debug.MemoryInfo();
14045                        }
14046                        if (!brief && !oomOnly) {
14047                            Debug.getMemoryInfo(st.pid, mi);
14048                        } else {
14049                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14050                            mi.nativePrivateDirty = (int)tmpLong[0];
14051                        }
14052
14053                        final long myTotalPss = mi.getTotalPss();
14054                        totalPss += myTotalPss;
14055                        nativeProcTotalPss += myTotalPss;
14056
14057                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14058                                st.name, myTotalPss, st.pid, false);
14059                        procMems.add(pssItem);
14060
14061                        nativePss += mi.nativePss;
14062                        dalvikPss += mi.dalvikPss;
14063                        otherPss += mi.otherPss;
14064                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14065                            long mem = mi.getOtherPss(j);
14066                            miscPss[j] += mem;
14067                            otherPss -= mem;
14068                        }
14069                        oomPss[0] += myTotalPss;
14070                        if (oomProcs[0] == null) {
14071                            oomProcs[0] = new ArrayList<MemItem>();
14072                        }
14073                        oomProcs[0].add(pssItem);
14074                    }
14075                }
14076            }
14077
14078            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14079
14080            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14081            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14082            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14083            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14084                String label = Debug.MemoryInfo.getOtherLabel(j);
14085                catMems.add(new MemItem(label, label, miscPss[j], j));
14086            }
14087
14088            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14089            for (int j=0; j<oomPss.length; j++) {
14090                if (oomPss[j] != 0) {
14091                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14092                            : DUMP_MEM_OOM_LABEL[j];
14093                    MemItem item = new MemItem(label, label, oomPss[j],
14094                            DUMP_MEM_OOM_ADJ[j]);
14095                    item.subitems = oomProcs[j];
14096                    oomMems.add(item);
14097                }
14098            }
14099
14100            if (!brief && !oomOnly && !isCompact) {
14101                pw.println();
14102                pw.println("Total PSS by process:");
14103                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14104                pw.println();
14105            }
14106            if (!isCompact) {
14107                pw.println("Total PSS by OOM adjustment:");
14108            }
14109            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14110            if (!brief && !oomOnly) {
14111                PrintWriter out = categoryPw != null ? categoryPw : pw;
14112                if (!isCompact) {
14113                    out.println();
14114                    out.println("Total PSS by category:");
14115                }
14116                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14117            }
14118            if (!isCompact) {
14119                pw.println();
14120            }
14121            MemInfoReader memInfo = new MemInfoReader();
14122            memInfo.readMemInfo();
14123            if (nativeProcTotalPss > 0) {
14124                synchronized (this) {
14125                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14126                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14127                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14128                }
14129            }
14130            if (!brief) {
14131                if (!isCompact) {
14132                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14133                    pw.print(" kB (status ");
14134                    switch (mLastMemoryLevel) {
14135                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14136                            pw.println("normal)");
14137                            break;
14138                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14139                            pw.println("moderate)");
14140                            break;
14141                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14142                            pw.println("low)");
14143                            break;
14144                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14145                            pw.println("critical)");
14146                            break;
14147                        default:
14148                            pw.print(mLastMemoryLevel);
14149                            pw.println(")");
14150                            break;
14151                    }
14152                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14153                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14154                            pw.print(cachedPss); pw.print(" cached pss + ");
14155                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14156                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14157                } else {
14158                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14159                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14160                            + memInfo.getFreeSizeKb()); pw.print(",");
14161                    pw.println(totalPss - cachedPss);
14162                }
14163            }
14164            if (!isCompact) {
14165                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14166                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14167                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14168                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14169                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14170                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14171                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14172            }
14173            if (!brief) {
14174                if (memInfo.getZramTotalSizeKb() != 0) {
14175                    if (!isCompact) {
14176                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14177                                pw.print(" kB physical used for ");
14178                                pw.print(memInfo.getSwapTotalSizeKb()
14179                                        - memInfo.getSwapFreeSizeKb());
14180                                pw.print(" kB in swap (");
14181                                pw.print(memInfo.getSwapTotalSizeKb());
14182                                pw.println(" kB total swap)");
14183                    } else {
14184                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14185                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14186                                pw.println(memInfo.getSwapFreeSizeKb());
14187                    }
14188                }
14189                final long[] ksm = getKsmInfo();
14190                if (!isCompact) {
14191                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14192                            || ksm[KSM_VOLATILE] != 0) {
14193                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14194                                pw.print(" kB saved from shared ");
14195                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14196                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14197                                pw.print(" kB unshared; ");
14198                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14199                    }
14200                    pw.print("   Tuning: ");
14201                    pw.print(ActivityManager.staticGetMemoryClass());
14202                    pw.print(" (large ");
14203                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14204                    pw.print("), oom ");
14205                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14206                    pw.print(" kB");
14207                    pw.print(", restore limit ");
14208                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14209                    pw.print(" kB");
14210                    if (ActivityManager.isLowRamDeviceStatic()) {
14211                        pw.print(" (low-ram)");
14212                    }
14213                    if (ActivityManager.isHighEndGfx()) {
14214                        pw.print(" (high-end-gfx)");
14215                    }
14216                    pw.println();
14217                } else {
14218                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14219                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14220                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14221                    pw.print("tuning,");
14222                    pw.print(ActivityManager.staticGetMemoryClass());
14223                    pw.print(',');
14224                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14225                    pw.print(',');
14226                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14227                    if (ActivityManager.isLowRamDeviceStatic()) {
14228                        pw.print(",low-ram");
14229                    }
14230                    if (ActivityManager.isHighEndGfx()) {
14231                        pw.print(",high-end-gfx");
14232                    }
14233                    pw.println();
14234                }
14235            }
14236        }
14237    }
14238
14239    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14240            String name) {
14241        sb.append("  ");
14242        sb.append(ProcessList.makeOomAdjString(oomAdj));
14243        sb.append(' ');
14244        sb.append(ProcessList.makeProcStateString(procState));
14245        sb.append(' ');
14246        ProcessList.appendRamKb(sb, pss);
14247        sb.append(" kB: ");
14248        sb.append(name);
14249    }
14250
14251    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14252        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14253        sb.append(" (");
14254        sb.append(mi.pid);
14255        sb.append(") ");
14256        sb.append(mi.adjType);
14257        sb.append('\n');
14258        if (mi.adjReason != null) {
14259            sb.append("                      ");
14260            sb.append(mi.adjReason);
14261            sb.append('\n');
14262        }
14263    }
14264
14265    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14266        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14267        for (int i=0, N=memInfos.size(); i<N; i++) {
14268            ProcessMemInfo mi = memInfos.get(i);
14269            infoMap.put(mi.pid, mi);
14270        }
14271        updateCpuStatsNow();
14272        synchronized (mProcessCpuTracker) {
14273            final int N = mProcessCpuTracker.countStats();
14274            for (int i=0; i<N; i++) {
14275                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14276                if (st.vsize > 0) {
14277                    long pss = Debug.getPss(st.pid, null);
14278                    if (pss > 0) {
14279                        if (infoMap.indexOfKey(st.pid) < 0) {
14280                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14281                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14282                            mi.pss = pss;
14283                            memInfos.add(mi);
14284                        }
14285                    }
14286                }
14287            }
14288        }
14289
14290        long totalPss = 0;
14291        for (int i=0, N=memInfos.size(); i<N; i++) {
14292            ProcessMemInfo mi = memInfos.get(i);
14293            if (mi.pss == 0) {
14294                mi.pss = Debug.getPss(mi.pid, null);
14295            }
14296            totalPss += mi.pss;
14297        }
14298        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14299            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14300                if (lhs.oomAdj != rhs.oomAdj) {
14301                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14302                }
14303                if (lhs.pss != rhs.pss) {
14304                    return lhs.pss < rhs.pss ? 1 : -1;
14305                }
14306                return 0;
14307            }
14308        });
14309
14310        StringBuilder tag = new StringBuilder(128);
14311        StringBuilder stack = new StringBuilder(128);
14312        tag.append("Low on memory -- ");
14313        appendMemBucket(tag, totalPss, "total", false);
14314        appendMemBucket(stack, totalPss, "total", true);
14315
14316        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14317        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14318        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14319
14320        boolean firstLine = true;
14321        int lastOomAdj = Integer.MIN_VALUE;
14322        long extraNativeRam = 0;
14323        long cachedPss = 0;
14324        for (int i=0, N=memInfos.size(); i<N; i++) {
14325            ProcessMemInfo mi = memInfos.get(i);
14326
14327            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14328                cachedPss += mi.pss;
14329            }
14330
14331            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14332                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14333                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14334                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14335                if (lastOomAdj != mi.oomAdj) {
14336                    lastOomAdj = mi.oomAdj;
14337                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14338                        tag.append(" / ");
14339                    }
14340                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14341                        if (firstLine) {
14342                            stack.append(":");
14343                            firstLine = false;
14344                        }
14345                        stack.append("\n\t at ");
14346                    } else {
14347                        stack.append("$");
14348                    }
14349                } else {
14350                    tag.append(" ");
14351                    stack.append("$");
14352                }
14353                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14354                    appendMemBucket(tag, mi.pss, mi.name, false);
14355                }
14356                appendMemBucket(stack, mi.pss, mi.name, true);
14357                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14358                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14359                    stack.append("(");
14360                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14361                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14362                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14363                            stack.append(":");
14364                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14365                        }
14366                    }
14367                    stack.append(")");
14368                }
14369            }
14370
14371            appendMemInfo(fullNativeBuilder, mi);
14372            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14373                // The short form only has native processes that are >= 1MB.
14374                if (mi.pss >= 1000) {
14375                    appendMemInfo(shortNativeBuilder, mi);
14376                } else {
14377                    extraNativeRam += mi.pss;
14378                }
14379            } else {
14380                // Short form has all other details, but if we have collected RAM
14381                // from smaller native processes let's dump a summary of that.
14382                if (extraNativeRam > 0) {
14383                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14384                            -1, extraNativeRam, "(Other native)");
14385                    shortNativeBuilder.append('\n');
14386                    extraNativeRam = 0;
14387                }
14388                appendMemInfo(fullJavaBuilder, mi);
14389            }
14390        }
14391
14392        fullJavaBuilder.append("           ");
14393        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14394        fullJavaBuilder.append(" kB: TOTAL\n");
14395
14396        MemInfoReader memInfo = new MemInfoReader();
14397        memInfo.readMemInfo();
14398        final long[] infos = memInfo.getRawInfo();
14399
14400        StringBuilder memInfoBuilder = new StringBuilder(1024);
14401        Debug.getMemInfo(infos);
14402        memInfoBuilder.append("  MemInfo: ");
14403        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14404        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14405        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14406        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14407        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14408        memInfoBuilder.append("           ");
14409        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14410        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14411        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14412        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14413        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14414            memInfoBuilder.append("  ZRAM: ");
14415            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14416            memInfoBuilder.append(" kB RAM, ");
14417            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14418            memInfoBuilder.append(" kB swap total, ");
14419            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14420            memInfoBuilder.append(" kB swap free\n");
14421        }
14422        final long[] ksm = getKsmInfo();
14423        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14424                || ksm[KSM_VOLATILE] != 0) {
14425            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14426            memInfoBuilder.append(" kB saved from shared ");
14427            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14428            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14429            memInfoBuilder.append(" kB unshared; ");
14430            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14431        }
14432        memInfoBuilder.append("  Free RAM: ");
14433        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14434                + memInfo.getFreeSizeKb());
14435        memInfoBuilder.append(" kB\n");
14436        memInfoBuilder.append("  Used RAM: ");
14437        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14438        memInfoBuilder.append(" kB\n");
14439        memInfoBuilder.append("  Lost RAM: ");
14440        memInfoBuilder.append(memInfo.getTotalSizeKb()
14441                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14442                - memInfo.getKernelUsedSizeKb());
14443        memInfoBuilder.append(" kB\n");
14444        Slog.i(TAG, "Low on memory:");
14445        Slog.i(TAG, shortNativeBuilder.toString());
14446        Slog.i(TAG, fullJavaBuilder.toString());
14447        Slog.i(TAG, memInfoBuilder.toString());
14448
14449        StringBuilder dropBuilder = new StringBuilder(1024);
14450        /*
14451        StringWriter oomSw = new StringWriter();
14452        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14453        StringWriter catSw = new StringWriter();
14454        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14455        String[] emptyArgs = new String[] { };
14456        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14457        oomPw.flush();
14458        String oomString = oomSw.toString();
14459        */
14460        dropBuilder.append("Low on memory:");
14461        dropBuilder.append(stack);
14462        dropBuilder.append('\n');
14463        dropBuilder.append(fullNativeBuilder);
14464        dropBuilder.append(fullJavaBuilder);
14465        dropBuilder.append('\n');
14466        dropBuilder.append(memInfoBuilder);
14467        dropBuilder.append('\n');
14468        /*
14469        dropBuilder.append(oomString);
14470        dropBuilder.append('\n');
14471        */
14472        StringWriter catSw = new StringWriter();
14473        synchronized (ActivityManagerService.this) {
14474            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14475            String[] emptyArgs = new String[] { };
14476            catPw.println();
14477            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14478            catPw.println();
14479            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14480                    false, false, null);
14481            catPw.println();
14482            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14483            catPw.flush();
14484        }
14485        dropBuilder.append(catSw.toString());
14486        addErrorToDropBox("lowmem", null, "system_server", null,
14487                null, tag.toString(), dropBuilder.toString(), null, null);
14488        //Slog.i(TAG, "Sent to dropbox:");
14489        //Slog.i(TAG, dropBuilder.toString());
14490        synchronized (ActivityManagerService.this) {
14491            long now = SystemClock.uptimeMillis();
14492            if (mLastMemUsageReportTime < now) {
14493                mLastMemUsageReportTime = now;
14494            }
14495        }
14496    }
14497
14498    /**
14499     * Searches array of arguments for the specified string
14500     * @param args array of argument strings
14501     * @param value value to search for
14502     * @return true if the value is contained in the array
14503     */
14504    private static boolean scanArgs(String[] args, String value) {
14505        if (args != null) {
14506            for (String arg : args) {
14507                if (value.equals(arg)) {
14508                    return true;
14509                }
14510            }
14511        }
14512        return false;
14513    }
14514
14515    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14516            ContentProviderRecord cpr, boolean always) {
14517        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14518
14519        if (!inLaunching || always) {
14520            synchronized (cpr) {
14521                cpr.launchingApp = null;
14522                cpr.notifyAll();
14523            }
14524            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14525            String names[] = cpr.info.authority.split(";");
14526            for (int j = 0; j < names.length; j++) {
14527                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14528            }
14529        }
14530
14531        for (int i=0; i<cpr.connections.size(); i++) {
14532            ContentProviderConnection conn = cpr.connections.get(i);
14533            if (conn.waiting) {
14534                // If this connection is waiting for the provider, then we don't
14535                // need to mess with its process unless we are always removing
14536                // or for some reason the provider is not currently launching.
14537                if (inLaunching && !always) {
14538                    continue;
14539                }
14540            }
14541            ProcessRecord capp = conn.client;
14542            conn.dead = true;
14543            if (conn.stableCount > 0) {
14544                if (!capp.persistent && capp.thread != null
14545                        && capp.pid != 0
14546                        && capp.pid != MY_PID) {
14547                    capp.kill("depends on provider "
14548                            + cpr.name.flattenToShortString()
14549                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14550                }
14551            } else if (capp.thread != null && conn.provider.provider != null) {
14552                try {
14553                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14554                } catch (RemoteException e) {
14555                }
14556                // In the protocol here, we don't expect the client to correctly
14557                // clean up this connection, we'll just remove it.
14558                cpr.connections.remove(i);
14559                conn.client.conProviders.remove(conn);
14560            }
14561        }
14562
14563        if (inLaunching && always) {
14564            mLaunchingProviders.remove(cpr);
14565        }
14566        return inLaunching;
14567    }
14568
14569    /**
14570     * Main code for cleaning up a process when it has gone away.  This is
14571     * called both as a result of the process dying, or directly when stopping
14572     * a process when running in single process mode.
14573     *
14574     * @return Returns true if the given process has been restarted, so the
14575     * app that was passed in must remain on the process lists.
14576     */
14577    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14578            boolean restarting, boolean allowRestart, int index) {
14579        if (index >= 0) {
14580            removeLruProcessLocked(app);
14581            ProcessList.remove(app.pid);
14582        }
14583
14584        mProcessesToGc.remove(app);
14585        mPendingPssProcesses.remove(app);
14586
14587        // Dismiss any open dialogs.
14588        if (app.crashDialog != null && !app.forceCrashReport) {
14589            app.crashDialog.dismiss();
14590            app.crashDialog = null;
14591        }
14592        if (app.anrDialog != null) {
14593            app.anrDialog.dismiss();
14594            app.anrDialog = null;
14595        }
14596        if (app.waitDialog != null) {
14597            app.waitDialog.dismiss();
14598            app.waitDialog = null;
14599        }
14600
14601        app.crashing = false;
14602        app.notResponding = false;
14603
14604        app.resetPackageList(mProcessStats);
14605        app.unlinkDeathRecipient();
14606        app.makeInactive(mProcessStats);
14607        app.waitingToKill = null;
14608        app.forcingToForeground = null;
14609        updateProcessForegroundLocked(app, false, false);
14610        app.foregroundActivities = false;
14611        app.hasShownUi = false;
14612        app.treatLikeActivity = false;
14613        app.hasAboveClient = false;
14614        app.hasClientActivities = false;
14615
14616        mServices.killServicesLocked(app, allowRestart);
14617
14618        boolean restart = false;
14619
14620        // Remove published content providers.
14621        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14622            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14623            final boolean always = app.bad || !allowRestart;
14624            if (removeDyingProviderLocked(app, cpr, always) || always) {
14625                // We left the provider in the launching list, need to
14626                // restart it.
14627                restart = true;
14628            }
14629
14630            cpr.provider = null;
14631            cpr.proc = null;
14632        }
14633        app.pubProviders.clear();
14634
14635        // Take care of any launching providers waiting for this process.
14636        if (checkAppInLaunchingProvidersLocked(app, false)) {
14637            restart = true;
14638        }
14639
14640        // Unregister from connected content providers.
14641        if (!app.conProviders.isEmpty()) {
14642            for (int i=0; i<app.conProviders.size(); i++) {
14643                ContentProviderConnection conn = app.conProviders.get(i);
14644                conn.provider.connections.remove(conn);
14645            }
14646            app.conProviders.clear();
14647        }
14648
14649        // At this point there may be remaining entries in mLaunchingProviders
14650        // where we were the only one waiting, so they are no longer of use.
14651        // Look for these and clean up if found.
14652        // XXX Commented out for now.  Trying to figure out a way to reproduce
14653        // the actual situation to identify what is actually going on.
14654        if (false) {
14655            for (int i=0; i<mLaunchingProviders.size(); i++) {
14656                ContentProviderRecord cpr = (ContentProviderRecord)
14657                        mLaunchingProviders.get(i);
14658                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14659                    synchronized (cpr) {
14660                        cpr.launchingApp = null;
14661                        cpr.notifyAll();
14662                    }
14663                }
14664            }
14665        }
14666
14667        skipCurrentReceiverLocked(app);
14668
14669        // Unregister any receivers.
14670        for (int i=app.receivers.size()-1; i>=0; i--) {
14671            removeReceiverLocked(app.receivers.valueAt(i));
14672        }
14673        app.receivers.clear();
14674
14675        // If the app is undergoing backup, tell the backup manager about it
14676        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14677            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14678                    + mBackupTarget.appInfo + " died during backup");
14679            try {
14680                IBackupManager bm = IBackupManager.Stub.asInterface(
14681                        ServiceManager.getService(Context.BACKUP_SERVICE));
14682                bm.agentDisconnected(app.info.packageName);
14683            } catch (RemoteException e) {
14684                // can't happen; backup manager is local
14685            }
14686        }
14687
14688        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14689            ProcessChangeItem item = mPendingProcessChanges.get(i);
14690            if (item.pid == app.pid) {
14691                mPendingProcessChanges.remove(i);
14692                mAvailProcessChanges.add(item);
14693            }
14694        }
14695        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14696
14697        // If the caller is restarting this app, then leave it in its
14698        // current lists and let the caller take care of it.
14699        if (restarting) {
14700            return false;
14701        }
14702
14703        if (!app.persistent || app.isolated) {
14704            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14705                    "Removing non-persistent process during cleanup: " + app);
14706            mProcessNames.remove(app.processName, app.uid);
14707            mIsolatedProcesses.remove(app.uid);
14708            if (mHeavyWeightProcess == app) {
14709                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14710                        mHeavyWeightProcess.userId, 0));
14711                mHeavyWeightProcess = null;
14712            }
14713        } else if (!app.removed) {
14714            // This app is persistent, so we need to keep its record around.
14715            // If it is not already on the pending app list, add it there
14716            // and start a new process for it.
14717            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14718                mPersistentStartingProcesses.add(app);
14719                restart = true;
14720            }
14721        }
14722        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14723                "Clean-up removing on hold: " + app);
14724        mProcessesOnHold.remove(app);
14725
14726        if (app == mHomeProcess) {
14727            mHomeProcess = null;
14728        }
14729        if (app == mPreviousProcess) {
14730            mPreviousProcess = null;
14731        }
14732
14733        if (restart && !app.isolated) {
14734            // We have components that still need to be running in the
14735            // process, so re-launch it.
14736            if (index < 0) {
14737                ProcessList.remove(app.pid);
14738            }
14739            mProcessNames.put(app.processName, app.uid, app);
14740            startProcessLocked(app, "restart", app.processName);
14741            return true;
14742        } else if (app.pid > 0 && app.pid != MY_PID) {
14743            // Goodbye!
14744            boolean removed;
14745            synchronized (mPidsSelfLocked) {
14746                mPidsSelfLocked.remove(app.pid);
14747                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14748            }
14749            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14750            if (app.isolated) {
14751                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14752            }
14753            app.setPid(0);
14754        }
14755        return false;
14756    }
14757
14758    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14759        // Look through the content providers we are waiting to have launched,
14760        // and if any run in this process then either schedule a restart of
14761        // the process or kill the client waiting for it if this process has
14762        // gone bad.
14763        int NL = mLaunchingProviders.size();
14764        boolean restart = false;
14765        for (int i=0; i<NL; i++) {
14766            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14767            if (cpr.launchingApp == app) {
14768                if (!alwaysBad && !app.bad) {
14769                    restart = true;
14770                } else {
14771                    removeDyingProviderLocked(app, cpr, true);
14772                    // cpr should have been removed from mLaunchingProviders
14773                    NL = mLaunchingProviders.size();
14774                    i--;
14775                }
14776            }
14777        }
14778        return restart;
14779    }
14780
14781    // =========================================================
14782    // SERVICES
14783    // =========================================================
14784
14785    @Override
14786    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14787            int flags) {
14788        enforceNotIsolatedCaller("getServices");
14789        synchronized (this) {
14790            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14791        }
14792    }
14793
14794    @Override
14795    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14796        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14797        synchronized (this) {
14798            return mServices.getRunningServiceControlPanelLocked(name);
14799        }
14800    }
14801
14802    @Override
14803    public ComponentName startService(IApplicationThread caller, Intent service,
14804            String resolvedType, int userId) {
14805        enforceNotIsolatedCaller("startService");
14806        // Refuse possible leaked file descriptors
14807        if (service != null && service.hasFileDescriptors() == true) {
14808            throw new IllegalArgumentException("File descriptors passed in Intent");
14809        }
14810
14811        if (DEBUG_SERVICE)
14812            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14813        synchronized(this) {
14814            final int callingPid = Binder.getCallingPid();
14815            final int callingUid = Binder.getCallingUid();
14816            final long origId = Binder.clearCallingIdentity();
14817            ComponentName res = mServices.startServiceLocked(caller, service,
14818                    resolvedType, callingPid, callingUid, userId);
14819            Binder.restoreCallingIdentity(origId);
14820            return res;
14821        }
14822    }
14823
14824    ComponentName startServiceInPackage(int uid,
14825            Intent service, String resolvedType, int userId) {
14826        synchronized(this) {
14827            if (DEBUG_SERVICE)
14828                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14829            final long origId = Binder.clearCallingIdentity();
14830            ComponentName res = mServices.startServiceLocked(null, service,
14831                    resolvedType, -1, uid, userId);
14832            Binder.restoreCallingIdentity(origId);
14833            return res;
14834        }
14835    }
14836
14837    @Override
14838    public int stopService(IApplicationThread caller, Intent service,
14839            String resolvedType, int userId) {
14840        enforceNotIsolatedCaller("stopService");
14841        // Refuse possible leaked file descriptors
14842        if (service != null && service.hasFileDescriptors() == true) {
14843            throw new IllegalArgumentException("File descriptors passed in Intent");
14844        }
14845
14846        synchronized(this) {
14847            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14848        }
14849    }
14850
14851    @Override
14852    public IBinder peekService(Intent service, String resolvedType) {
14853        enforceNotIsolatedCaller("peekService");
14854        // Refuse possible leaked file descriptors
14855        if (service != null && service.hasFileDescriptors() == true) {
14856            throw new IllegalArgumentException("File descriptors passed in Intent");
14857        }
14858        synchronized(this) {
14859            return mServices.peekServiceLocked(service, resolvedType);
14860        }
14861    }
14862
14863    @Override
14864    public boolean stopServiceToken(ComponentName className, IBinder token,
14865            int startId) {
14866        synchronized(this) {
14867            return mServices.stopServiceTokenLocked(className, token, startId);
14868        }
14869    }
14870
14871    @Override
14872    public void setServiceForeground(ComponentName className, IBinder token,
14873            int id, Notification notification, boolean removeNotification) {
14874        synchronized(this) {
14875            mServices.setServiceForegroundLocked(className, token, id, notification,
14876                    removeNotification);
14877        }
14878    }
14879
14880    @Override
14881    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14882            boolean requireFull, String name, String callerPackage) {
14883        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14884                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14885    }
14886
14887    int unsafeConvertIncomingUser(int userId) {
14888        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14889                ? mCurrentUserId : userId;
14890    }
14891
14892    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14893            int allowMode, String name, String callerPackage) {
14894        final int callingUserId = UserHandle.getUserId(callingUid);
14895        if (callingUserId == userId) {
14896            return userId;
14897        }
14898
14899        // Note that we may be accessing mCurrentUserId outside of a lock...
14900        // shouldn't be a big deal, if this is being called outside
14901        // of a locked context there is intrinsically a race with
14902        // the value the caller will receive and someone else changing it.
14903        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14904        // we will switch to the calling user if access to the current user fails.
14905        int targetUserId = unsafeConvertIncomingUser(userId);
14906
14907        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14908            final boolean allow;
14909            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14910                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14911                // If the caller has this permission, they always pass go.  And collect $200.
14912                allow = true;
14913            } else if (allowMode == ALLOW_FULL_ONLY) {
14914                // We require full access, sucks to be you.
14915                allow = false;
14916            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14917                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14918                // If the caller does not have either permission, they are always doomed.
14919                allow = false;
14920            } else if (allowMode == ALLOW_NON_FULL) {
14921                // We are blanket allowing non-full access, you lucky caller!
14922                allow = true;
14923            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14924                // We may or may not allow this depending on whether the two users are
14925                // in the same profile.
14926                synchronized (mUserProfileGroupIdsSelfLocked) {
14927                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14928                            UserInfo.NO_PROFILE_GROUP_ID);
14929                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14930                            UserInfo.NO_PROFILE_GROUP_ID);
14931                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14932                            && callingProfile == targetProfile;
14933                }
14934            } else {
14935                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14936            }
14937            if (!allow) {
14938                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14939                    // In this case, they would like to just execute as their
14940                    // owner user instead of failing.
14941                    targetUserId = callingUserId;
14942                } else {
14943                    StringBuilder builder = new StringBuilder(128);
14944                    builder.append("Permission Denial: ");
14945                    builder.append(name);
14946                    if (callerPackage != null) {
14947                        builder.append(" from ");
14948                        builder.append(callerPackage);
14949                    }
14950                    builder.append(" asks to run as user ");
14951                    builder.append(userId);
14952                    builder.append(" but is calling from user ");
14953                    builder.append(UserHandle.getUserId(callingUid));
14954                    builder.append("; this requires ");
14955                    builder.append(INTERACT_ACROSS_USERS_FULL);
14956                    if (allowMode != ALLOW_FULL_ONLY) {
14957                        builder.append(" or ");
14958                        builder.append(INTERACT_ACROSS_USERS);
14959                    }
14960                    String msg = builder.toString();
14961                    Slog.w(TAG, msg);
14962                    throw new SecurityException(msg);
14963                }
14964            }
14965        }
14966        if (!allowAll && targetUserId < 0) {
14967            throw new IllegalArgumentException(
14968                    "Call does not support special user #" + targetUserId);
14969        }
14970        // Check shell permission
14971        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14972            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14973                    targetUserId)) {
14974                throw new SecurityException("Shell does not have permission to access user "
14975                        + targetUserId + "\n " + Debug.getCallers(3));
14976            }
14977        }
14978        return targetUserId;
14979    }
14980
14981    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14982            String className, int flags) {
14983        boolean result = false;
14984        // For apps that don't have pre-defined UIDs, check for permission
14985        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14986            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14987                if (ActivityManager.checkUidPermission(
14988                        INTERACT_ACROSS_USERS,
14989                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14990                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14991                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14992                            + " requests FLAG_SINGLE_USER, but app does not hold "
14993                            + INTERACT_ACROSS_USERS;
14994                    Slog.w(TAG, msg);
14995                    throw new SecurityException(msg);
14996                }
14997                // Permission passed
14998                result = true;
14999            }
15000        } else if ("system".equals(componentProcessName)) {
15001            result = true;
15002        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15003            // Phone app and persistent apps are allowed to export singleuser providers.
15004            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15005                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15006        }
15007        if (DEBUG_MU) {
15008            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15009                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15010        }
15011        return result;
15012    }
15013
15014    /**
15015     * Checks to see if the caller is in the same app as the singleton
15016     * component, or the component is in a special app. It allows special apps
15017     * to export singleton components but prevents exporting singleton
15018     * components for regular apps.
15019     */
15020    boolean isValidSingletonCall(int callingUid, int componentUid) {
15021        int componentAppId = UserHandle.getAppId(componentUid);
15022        return UserHandle.isSameApp(callingUid, componentUid)
15023                || componentAppId == Process.SYSTEM_UID
15024                || componentAppId == Process.PHONE_UID
15025                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15026                        == PackageManager.PERMISSION_GRANTED;
15027    }
15028
15029    public int bindService(IApplicationThread caller, IBinder token,
15030            Intent service, String resolvedType,
15031            IServiceConnection connection, int flags, int userId) {
15032        enforceNotIsolatedCaller("bindService");
15033
15034        // Refuse possible leaked file descriptors
15035        if (service != null && service.hasFileDescriptors() == true) {
15036            throw new IllegalArgumentException("File descriptors passed in Intent");
15037        }
15038
15039        synchronized(this) {
15040            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15041                    connection, flags, userId);
15042        }
15043    }
15044
15045    public boolean unbindService(IServiceConnection connection) {
15046        synchronized (this) {
15047            return mServices.unbindServiceLocked(connection);
15048        }
15049    }
15050
15051    public void publishService(IBinder token, Intent intent, IBinder service) {
15052        // Refuse possible leaked file descriptors
15053        if (intent != null && intent.hasFileDescriptors() == true) {
15054            throw new IllegalArgumentException("File descriptors passed in Intent");
15055        }
15056
15057        synchronized(this) {
15058            if (!(token instanceof ServiceRecord)) {
15059                throw new IllegalArgumentException("Invalid service token");
15060            }
15061            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15062        }
15063    }
15064
15065    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15066        // Refuse possible leaked file descriptors
15067        if (intent != null && intent.hasFileDescriptors() == true) {
15068            throw new IllegalArgumentException("File descriptors passed in Intent");
15069        }
15070
15071        synchronized(this) {
15072            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15073        }
15074    }
15075
15076    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15077        synchronized(this) {
15078            if (!(token instanceof ServiceRecord)) {
15079                throw new IllegalArgumentException("Invalid service token");
15080            }
15081            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15082        }
15083    }
15084
15085    // =========================================================
15086    // BACKUP AND RESTORE
15087    // =========================================================
15088
15089    // Cause the target app to be launched if necessary and its backup agent
15090    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15091    // activity manager to announce its creation.
15092    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15093        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15094        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15095
15096        synchronized(this) {
15097            // !!! TODO: currently no check here that we're already bound
15098            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15099            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15100            synchronized (stats) {
15101                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15102            }
15103
15104            // Backup agent is now in use, its package can't be stopped.
15105            try {
15106                AppGlobals.getPackageManager().setPackageStoppedState(
15107                        app.packageName, false, UserHandle.getUserId(app.uid));
15108            } catch (RemoteException e) {
15109            } catch (IllegalArgumentException e) {
15110                Slog.w(TAG, "Failed trying to unstop package "
15111                        + app.packageName + ": " + e);
15112            }
15113
15114            BackupRecord r = new BackupRecord(ss, app, backupMode);
15115            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15116                    ? new ComponentName(app.packageName, app.backupAgentName)
15117                    : new ComponentName("android", "FullBackupAgent");
15118            // startProcessLocked() returns existing proc's record if it's already running
15119            ProcessRecord proc = startProcessLocked(app.processName, app,
15120                    false, 0, "backup", hostingName, false, false, false);
15121            if (proc == null) {
15122                Slog.e(TAG, "Unable to start backup agent process " + r);
15123                return false;
15124            }
15125
15126            r.app = proc;
15127            mBackupTarget = r;
15128            mBackupAppName = app.packageName;
15129
15130            // Try not to kill the process during backup
15131            updateOomAdjLocked(proc);
15132
15133            // If the process is already attached, schedule the creation of the backup agent now.
15134            // If it is not yet live, this will be done when it attaches to the framework.
15135            if (proc.thread != null) {
15136                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15137                try {
15138                    proc.thread.scheduleCreateBackupAgent(app,
15139                            compatibilityInfoForPackageLocked(app), backupMode);
15140                } catch (RemoteException e) {
15141                    // Will time out on the backup manager side
15142                }
15143            } else {
15144                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15145            }
15146            // Invariants: at this point, the target app process exists and the application
15147            // is either already running or in the process of coming up.  mBackupTarget and
15148            // mBackupAppName describe the app, so that when it binds back to the AM we
15149            // know that it's scheduled for a backup-agent operation.
15150        }
15151
15152        return true;
15153    }
15154
15155    @Override
15156    public void clearPendingBackup() {
15157        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15158        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15159
15160        synchronized (this) {
15161            mBackupTarget = null;
15162            mBackupAppName = null;
15163        }
15164    }
15165
15166    // A backup agent has just come up
15167    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15168        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15169                + " = " + agent);
15170
15171        synchronized(this) {
15172            if (!agentPackageName.equals(mBackupAppName)) {
15173                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15174                return;
15175            }
15176        }
15177
15178        long oldIdent = Binder.clearCallingIdentity();
15179        try {
15180            IBackupManager bm = IBackupManager.Stub.asInterface(
15181                    ServiceManager.getService(Context.BACKUP_SERVICE));
15182            bm.agentConnected(agentPackageName, agent);
15183        } catch (RemoteException e) {
15184            // can't happen; the backup manager service is local
15185        } catch (Exception e) {
15186            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15187            e.printStackTrace();
15188        } finally {
15189            Binder.restoreCallingIdentity(oldIdent);
15190        }
15191    }
15192
15193    // done with this agent
15194    public void unbindBackupAgent(ApplicationInfo appInfo) {
15195        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15196        if (appInfo == null) {
15197            Slog.w(TAG, "unbind backup agent for null app");
15198            return;
15199        }
15200
15201        synchronized(this) {
15202            try {
15203                if (mBackupAppName == null) {
15204                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15205                    return;
15206                }
15207
15208                if (!mBackupAppName.equals(appInfo.packageName)) {
15209                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15210                    return;
15211                }
15212
15213                // Not backing this app up any more; reset its OOM adjustment
15214                final ProcessRecord proc = mBackupTarget.app;
15215                updateOomAdjLocked(proc);
15216
15217                // If the app crashed during backup, 'thread' will be null here
15218                if (proc.thread != null) {
15219                    try {
15220                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15221                                compatibilityInfoForPackageLocked(appInfo));
15222                    } catch (Exception e) {
15223                        Slog.e(TAG, "Exception when unbinding backup agent:");
15224                        e.printStackTrace();
15225                    }
15226                }
15227            } finally {
15228                mBackupTarget = null;
15229                mBackupAppName = null;
15230            }
15231        }
15232    }
15233    // =========================================================
15234    // BROADCASTS
15235    // =========================================================
15236
15237    private final List getStickiesLocked(String action, IntentFilter filter,
15238            List cur, int userId) {
15239        final ContentResolver resolver = mContext.getContentResolver();
15240        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15241        if (stickies == null) {
15242            return cur;
15243        }
15244        final ArrayList<Intent> list = stickies.get(action);
15245        if (list == null) {
15246            return cur;
15247        }
15248        int N = list.size();
15249        for (int i=0; i<N; i++) {
15250            Intent intent = list.get(i);
15251            if (filter.match(resolver, intent, true, TAG) >= 0) {
15252                if (cur == null) {
15253                    cur = new ArrayList<Intent>();
15254                }
15255                cur.add(intent);
15256            }
15257        }
15258        return cur;
15259    }
15260
15261    boolean isPendingBroadcastProcessLocked(int pid) {
15262        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15263                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15264    }
15265
15266    void skipPendingBroadcastLocked(int pid) {
15267            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15268            for (BroadcastQueue queue : mBroadcastQueues) {
15269                queue.skipPendingBroadcastLocked(pid);
15270            }
15271    }
15272
15273    // The app just attached; send any pending broadcasts that it should receive
15274    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15275        boolean didSomething = false;
15276        for (BroadcastQueue queue : mBroadcastQueues) {
15277            didSomething |= queue.sendPendingBroadcastsLocked(app);
15278        }
15279        return didSomething;
15280    }
15281
15282    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15283            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15284        enforceNotIsolatedCaller("registerReceiver");
15285        int callingUid;
15286        int callingPid;
15287        synchronized(this) {
15288            ProcessRecord callerApp = null;
15289            if (caller != null) {
15290                callerApp = getRecordForAppLocked(caller);
15291                if (callerApp == null) {
15292                    throw new SecurityException(
15293                            "Unable to find app for caller " + caller
15294                            + " (pid=" + Binder.getCallingPid()
15295                            + ") when registering receiver " + receiver);
15296                }
15297                if (callerApp.info.uid != Process.SYSTEM_UID &&
15298                        !callerApp.pkgList.containsKey(callerPackage) &&
15299                        !"android".equals(callerPackage)) {
15300                    throw new SecurityException("Given caller package " + callerPackage
15301                            + " is not running in process " + callerApp);
15302                }
15303                callingUid = callerApp.info.uid;
15304                callingPid = callerApp.pid;
15305            } else {
15306                callerPackage = null;
15307                callingUid = Binder.getCallingUid();
15308                callingPid = Binder.getCallingPid();
15309            }
15310
15311            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15312                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15313
15314            List allSticky = null;
15315
15316            // Look for any matching sticky broadcasts...
15317            Iterator actions = filter.actionsIterator();
15318            if (actions != null) {
15319                while (actions.hasNext()) {
15320                    String action = (String)actions.next();
15321                    allSticky = getStickiesLocked(action, filter, allSticky,
15322                            UserHandle.USER_ALL);
15323                    allSticky = getStickiesLocked(action, filter, allSticky,
15324                            UserHandle.getUserId(callingUid));
15325                }
15326            } else {
15327                allSticky = getStickiesLocked(null, filter, allSticky,
15328                        UserHandle.USER_ALL);
15329                allSticky = getStickiesLocked(null, filter, allSticky,
15330                        UserHandle.getUserId(callingUid));
15331            }
15332
15333            // The first sticky in the list is returned directly back to
15334            // the client.
15335            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15336
15337            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15338                    + ": " + sticky);
15339
15340            if (receiver == null) {
15341                return sticky;
15342            }
15343
15344            ReceiverList rl
15345                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15346            if (rl == null) {
15347                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15348                        userId, receiver);
15349                if (rl.app != null) {
15350                    rl.app.receivers.add(rl);
15351                } else {
15352                    try {
15353                        receiver.asBinder().linkToDeath(rl, 0);
15354                    } catch (RemoteException e) {
15355                        return sticky;
15356                    }
15357                    rl.linkedToDeath = true;
15358                }
15359                mRegisteredReceivers.put(receiver.asBinder(), rl);
15360            } else if (rl.uid != callingUid) {
15361                throw new IllegalArgumentException(
15362                        "Receiver requested to register for uid " + callingUid
15363                        + " was previously registered for uid " + rl.uid);
15364            } else if (rl.pid != callingPid) {
15365                throw new IllegalArgumentException(
15366                        "Receiver requested to register for pid " + callingPid
15367                        + " was previously registered for pid " + rl.pid);
15368            } else if (rl.userId != userId) {
15369                throw new IllegalArgumentException(
15370                        "Receiver requested to register for user " + userId
15371                        + " was previously registered for user " + rl.userId);
15372            }
15373            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15374                    permission, callingUid, userId);
15375            rl.add(bf);
15376            if (!bf.debugCheck()) {
15377                Slog.w(TAG, "==> For Dynamic broadast");
15378            }
15379            mReceiverResolver.addFilter(bf);
15380
15381            // Enqueue broadcasts for all existing stickies that match
15382            // this filter.
15383            if (allSticky != null) {
15384                ArrayList receivers = new ArrayList();
15385                receivers.add(bf);
15386
15387                int N = allSticky.size();
15388                for (int i=0; i<N; i++) {
15389                    Intent intent = (Intent)allSticky.get(i);
15390                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15391                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15392                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15393                            null, null, false, true, true, -1);
15394                    queue.enqueueParallelBroadcastLocked(r);
15395                    queue.scheduleBroadcastsLocked();
15396                }
15397            }
15398
15399            return sticky;
15400        }
15401    }
15402
15403    public void unregisterReceiver(IIntentReceiver receiver) {
15404        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15405
15406        final long origId = Binder.clearCallingIdentity();
15407        try {
15408            boolean doTrim = false;
15409
15410            synchronized(this) {
15411                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15412                if (rl != null) {
15413                    if (rl.curBroadcast != null) {
15414                        BroadcastRecord r = rl.curBroadcast;
15415                        final boolean doNext = finishReceiverLocked(
15416                                receiver.asBinder(), r.resultCode, r.resultData,
15417                                r.resultExtras, r.resultAbort);
15418                        if (doNext) {
15419                            doTrim = true;
15420                            r.queue.processNextBroadcast(false);
15421                        }
15422                    }
15423
15424                    if (rl.app != null) {
15425                        rl.app.receivers.remove(rl);
15426                    }
15427                    removeReceiverLocked(rl);
15428                    if (rl.linkedToDeath) {
15429                        rl.linkedToDeath = false;
15430                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15431                    }
15432                }
15433            }
15434
15435            // If we actually concluded any broadcasts, we might now be able
15436            // to trim the recipients' apps from our working set
15437            if (doTrim) {
15438                trimApplications();
15439                return;
15440            }
15441
15442        } finally {
15443            Binder.restoreCallingIdentity(origId);
15444        }
15445    }
15446
15447    void removeReceiverLocked(ReceiverList rl) {
15448        mRegisteredReceivers.remove(rl.receiver.asBinder());
15449        int N = rl.size();
15450        for (int i=0; i<N; i++) {
15451            mReceiverResolver.removeFilter(rl.get(i));
15452        }
15453    }
15454
15455    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15456        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15457            ProcessRecord r = mLruProcesses.get(i);
15458            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15459                try {
15460                    r.thread.dispatchPackageBroadcast(cmd, packages);
15461                } catch (RemoteException ex) {
15462                }
15463            }
15464        }
15465    }
15466
15467    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15468            int callingUid, int[] users) {
15469        List<ResolveInfo> receivers = null;
15470        try {
15471            HashSet<ComponentName> singleUserReceivers = null;
15472            boolean scannedFirstReceivers = false;
15473            for (int user : users) {
15474                // Skip users that have Shell restrictions
15475                if (callingUid == Process.SHELL_UID
15476                        && getUserManagerLocked().hasUserRestriction(
15477                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15478                    continue;
15479                }
15480                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15481                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15482                if (user != 0 && newReceivers != null) {
15483                    // If this is not the primary user, we need to check for
15484                    // any receivers that should be filtered out.
15485                    for (int i=0; i<newReceivers.size(); i++) {
15486                        ResolveInfo ri = newReceivers.get(i);
15487                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15488                            newReceivers.remove(i);
15489                            i--;
15490                        }
15491                    }
15492                }
15493                if (newReceivers != null && newReceivers.size() == 0) {
15494                    newReceivers = null;
15495                }
15496                if (receivers == null) {
15497                    receivers = newReceivers;
15498                } else if (newReceivers != null) {
15499                    // We need to concatenate the additional receivers
15500                    // found with what we have do far.  This would be easy,
15501                    // but we also need to de-dup any receivers that are
15502                    // singleUser.
15503                    if (!scannedFirstReceivers) {
15504                        // Collect any single user receivers we had already retrieved.
15505                        scannedFirstReceivers = true;
15506                        for (int i=0; i<receivers.size(); i++) {
15507                            ResolveInfo ri = receivers.get(i);
15508                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15509                                ComponentName cn = new ComponentName(
15510                                        ri.activityInfo.packageName, ri.activityInfo.name);
15511                                if (singleUserReceivers == null) {
15512                                    singleUserReceivers = new HashSet<ComponentName>();
15513                                }
15514                                singleUserReceivers.add(cn);
15515                            }
15516                        }
15517                    }
15518                    // Add the new results to the existing results, tracking
15519                    // and de-dupping single user receivers.
15520                    for (int i=0; i<newReceivers.size(); i++) {
15521                        ResolveInfo ri = newReceivers.get(i);
15522                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15523                            ComponentName cn = new ComponentName(
15524                                    ri.activityInfo.packageName, ri.activityInfo.name);
15525                            if (singleUserReceivers == null) {
15526                                singleUserReceivers = new HashSet<ComponentName>();
15527                            }
15528                            if (!singleUserReceivers.contains(cn)) {
15529                                singleUserReceivers.add(cn);
15530                                receivers.add(ri);
15531                            }
15532                        } else {
15533                            receivers.add(ri);
15534                        }
15535                    }
15536                }
15537            }
15538        } catch (RemoteException ex) {
15539            // pm is in same process, this will never happen.
15540        }
15541        return receivers;
15542    }
15543
15544    private final int broadcastIntentLocked(ProcessRecord callerApp,
15545            String callerPackage, Intent intent, String resolvedType,
15546            IIntentReceiver resultTo, int resultCode, String resultData,
15547            Bundle map, String requiredPermission, int appOp,
15548            boolean ordered, boolean sticky, int callingPid, int callingUid,
15549            int userId) {
15550        intent = new Intent(intent);
15551
15552        // By default broadcasts do not go to stopped apps.
15553        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15554
15555        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15556            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15557            + " ordered=" + ordered + " userid=" + userId);
15558        if ((resultTo != null) && !ordered) {
15559            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15560        }
15561
15562        userId = handleIncomingUser(callingPid, callingUid, userId,
15563                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15564
15565        // Make sure that the user who is receiving this broadcast is started.
15566        // If not, we will just skip it.
15567
15568        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15569            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15570                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15571                Slog.w(TAG, "Skipping broadcast of " + intent
15572                        + ": user " + userId + " is stopped");
15573                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15574            }
15575        }
15576
15577        /*
15578         * Prevent non-system code (defined here to be non-persistent
15579         * processes) from sending protected broadcasts.
15580         */
15581        int callingAppId = UserHandle.getAppId(callingUid);
15582        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15583            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15584            || callingAppId == Process.NFC_UID || callingUid == 0) {
15585            // Always okay.
15586        } else if (callerApp == null || !callerApp.persistent) {
15587            try {
15588                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15589                        intent.getAction())) {
15590                    String msg = "Permission Denial: not allowed to send broadcast "
15591                            + intent.getAction() + " from pid="
15592                            + callingPid + ", uid=" + callingUid;
15593                    Slog.w(TAG, msg);
15594                    throw new SecurityException(msg);
15595                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15596                    // Special case for compatibility: we don't want apps to send this,
15597                    // but historically it has not been protected and apps may be using it
15598                    // to poke their own app widget.  So, instead of making it protected,
15599                    // just limit it to the caller.
15600                    if (callerApp == null) {
15601                        String msg = "Permission Denial: not allowed to send broadcast "
15602                                + intent.getAction() + " from unknown caller.";
15603                        Slog.w(TAG, msg);
15604                        throw new SecurityException(msg);
15605                    } else if (intent.getComponent() != null) {
15606                        // They are good enough to send to an explicit component...  verify
15607                        // it is being sent to the calling app.
15608                        if (!intent.getComponent().getPackageName().equals(
15609                                callerApp.info.packageName)) {
15610                            String msg = "Permission Denial: not allowed to send broadcast "
15611                                    + intent.getAction() + " to "
15612                                    + intent.getComponent().getPackageName() + " from "
15613                                    + callerApp.info.packageName;
15614                            Slog.w(TAG, msg);
15615                            throw new SecurityException(msg);
15616                        }
15617                    } else {
15618                        // Limit broadcast to their own package.
15619                        intent.setPackage(callerApp.info.packageName);
15620                    }
15621                }
15622            } catch (RemoteException e) {
15623                Slog.w(TAG, "Remote exception", e);
15624                return ActivityManager.BROADCAST_SUCCESS;
15625            }
15626        }
15627
15628        final String action = intent.getAction();
15629        if (action != null) {
15630            switch (action) {
15631                case Intent.ACTION_UID_REMOVED:
15632                case Intent.ACTION_PACKAGE_REMOVED:
15633                case Intent.ACTION_PACKAGE_CHANGED:
15634                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15635                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15636                    // Handle special intents: if this broadcast is from the package
15637                    // manager about a package being removed, we need to remove all of
15638                    // its activities from the history stack.
15639                    if (checkComponentPermission(
15640                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15641                            callingPid, callingUid, -1, true)
15642                            != PackageManager.PERMISSION_GRANTED) {
15643                        String msg = "Permission Denial: " + intent.getAction()
15644                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15645                                + ", uid=" + callingUid + ")"
15646                                + " requires "
15647                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15648                        Slog.w(TAG, msg);
15649                        throw new SecurityException(msg);
15650                    }
15651                    switch (action) {
15652                        case Intent.ACTION_UID_REMOVED:
15653                            final Bundle intentExtras = intent.getExtras();
15654                            final int uid = intentExtras != null
15655                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15656                            if (uid >= 0) {
15657                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15658                                synchronized (bs) {
15659                                    bs.removeUidStatsLocked(uid);
15660                                }
15661                                mAppOpsService.uidRemoved(uid);
15662                            }
15663                            break;
15664                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15665                            // If resources are unavailable just force stop all those packages
15666                            // and flush the attribute cache as well.
15667                            String list[] =
15668                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15669                            if (list != null && list.length > 0) {
15670                                for (int i = 0; i < list.length; i++) {
15671                                    forceStopPackageLocked(list[i], -1, false, true, true,
15672                                            false, false, userId, "storage unmount");
15673                                }
15674                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15675                                sendPackageBroadcastLocked(
15676                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15677                                        userId);
15678                            }
15679                            break;
15680                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15681                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15682                            break;
15683                        case Intent.ACTION_PACKAGE_REMOVED:
15684                        case Intent.ACTION_PACKAGE_CHANGED:
15685                            Uri data = intent.getData();
15686                            String ssp;
15687                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15688                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15689                                boolean fullUninstall = removed &&
15690                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15691                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15692                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15693                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15694                                            false, true, true, false, fullUninstall, userId,
15695                                            removed ? "pkg removed" : "pkg changed");
15696                                }
15697                                if (removed) {
15698                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15699                                            new String[] {ssp}, userId);
15700                                    if (fullUninstall) {
15701                                        mAppOpsService.packageRemoved(
15702                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15703
15704                                        // Remove all permissions granted from/to this package
15705                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15706
15707                                        removeTasksByPackageNameLocked(ssp, userId);
15708                                    }
15709                                } else {
15710                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15711                                }
15712                            }
15713                            break;
15714                    }
15715                    break;
15716                case Intent.ACTION_PACKAGE_ADDED:
15717                    // Special case for adding a package: by default turn on compatibility mode.
15718                    Uri data = intent.getData();
15719                    String ssp;
15720                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15721                        final boolean replacing =
15722                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15723                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15724
15725                        if (replacing) {
15726                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15727                        }
15728                    }
15729                    break;
15730                case Intent.ACTION_TIMEZONE_CHANGED:
15731                    // If this is the time zone changed action, queue up a message that will reset
15732                    // the timezone of all currently running processes. This message will get
15733                    // queued up before the broadcast happens.
15734                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15735                    break;
15736                case Intent.ACTION_TIME_CHANGED:
15737                    // If the user set the time, let all running processes know.
15738                    final int is24Hour =
15739                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15740                                    : 0;
15741                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15742                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15743                    synchronized (stats) {
15744                        stats.noteCurrentTimeChangedLocked();
15745                    }
15746                    break;
15747                case Intent.ACTION_CLEAR_DNS_CACHE:
15748                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15749                    break;
15750                case Proxy.PROXY_CHANGE_ACTION:
15751                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15752                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15753                    break;
15754            }
15755        }
15756
15757        // Add to the sticky list if requested.
15758        if (sticky) {
15759            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15760                    callingPid, callingUid)
15761                    != PackageManager.PERMISSION_GRANTED) {
15762                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15763                        + callingPid + ", uid=" + callingUid
15764                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15765                Slog.w(TAG, msg);
15766                throw new SecurityException(msg);
15767            }
15768            if (requiredPermission != null) {
15769                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15770                        + " and enforce permission " + requiredPermission);
15771                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15772            }
15773            if (intent.getComponent() != null) {
15774                throw new SecurityException(
15775                        "Sticky broadcasts can't target a specific component");
15776            }
15777            // We use userId directly here, since the "all" target is maintained
15778            // as a separate set of sticky broadcasts.
15779            if (userId != UserHandle.USER_ALL) {
15780                // But first, if this is not a broadcast to all users, then
15781                // make sure it doesn't conflict with an existing broadcast to
15782                // all users.
15783                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15784                        UserHandle.USER_ALL);
15785                if (stickies != null) {
15786                    ArrayList<Intent> list = stickies.get(intent.getAction());
15787                    if (list != null) {
15788                        int N = list.size();
15789                        int i;
15790                        for (i=0; i<N; i++) {
15791                            if (intent.filterEquals(list.get(i))) {
15792                                throw new IllegalArgumentException(
15793                                        "Sticky broadcast " + intent + " for user "
15794                                        + userId + " conflicts with existing global broadcast");
15795                            }
15796                        }
15797                    }
15798                }
15799            }
15800            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15801            if (stickies == null) {
15802                stickies = new ArrayMap<String, ArrayList<Intent>>();
15803                mStickyBroadcasts.put(userId, stickies);
15804            }
15805            ArrayList<Intent> list = stickies.get(intent.getAction());
15806            if (list == null) {
15807                list = new ArrayList<Intent>();
15808                stickies.put(intent.getAction(), list);
15809            }
15810            int N = list.size();
15811            int i;
15812            for (i=0; i<N; i++) {
15813                if (intent.filterEquals(list.get(i))) {
15814                    // This sticky already exists, replace it.
15815                    list.set(i, new Intent(intent));
15816                    break;
15817                }
15818            }
15819            if (i >= N) {
15820                list.add(new Intent(intent));
15821            }
15822        }
15823
15824        int[] users;
15825        if (userId == UserHandle.USER_ALL) {
15826            // Caller wants broadcast to go to all started users.
15827            users = mStartedUserArray;
15828        } else {
15829            // Caller wants broadcast to go to one specific user.
15830            users = new int[] {userId};
15831        }
15832
15833        // Figure out who all will receive this broadcast.
15834        List receivers = null;
15835        List<BroadcastFilter> registeredReceivers = null;
15836        // Need to resolve the intent to interested receivers...
15837        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15838                 == 0) {
15839            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15840        }
15841        if (intent.getComponent() == null) {
15842            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15843                // Query one target user at a time, excluding shell-restricted users
15844                UserManagerService ums = getUserManagerLocked();
15845                for (int i = 0; i < users.length; i++) {
15846                    if (ums.hasUserRestriction(
15847                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15848                        continue;
15849                    }
15850                    List<BroadcastFilter> registeredReceiversForUser =
15851                            mReceiverResolver.queryIntent(intent,
15852                                    resolvedType, false, users[i]);
15853                    if (registeredReceivers == null) {
15854                        registeredReceivers = registeredReceiversForUser;
15855                    } else if (registeredReceiversForUser != null) {
15856                        registeredReceivers.addAll(registeredReceiversForUser);
15857                    }
15858                }
15859            } else {
15860                registeredReceivers = mReceiverResolver.queryIntent(intent,
15861                        resolvedType, false, userId);
15862            }
15863        }
15864
15865        final boolean replacePending =
15866                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15867
15868        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15869                + " replacePending=" + replacePending);
15870
15871        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15872        if (!ordered && NR > 0) {
15873            // If we are not serializing this broadcast, then send the
15874            // registered receivers separately so they don't wait for the
15875            // components to be launched.
15876            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15877            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15878                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15879                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15880                    ordered, sticky, false, userId);
15881            if (DEBUG_BROADCAST) Slog.v(
15882                    TAG, "Enqueueing parallel broadcast " + r);
15883            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15884            if (!replaced) {
15885                queue.enqueueParallelBroadcastLocked(r);
15886                queue.scheduleBroadcastsLocked();
15887            }
15888            registeredReceivers = null;
15889            NR = 0;
15890        }
15891
15892        // Merge into one list.
15893        int ir = 0;
15894        if (receivers != null) {
15895            // A special case for PACKAGE_ADDED: do not allow the package
15896            // being added to see this broadcast.  This prevents them from
15897            // using this as a back door to get run as soon as they are
15898            // installed.  Maybe in the future we want to have a special install
15899            // broadcast or such for apps, but we'd like to deliberately make
15900            // this decision.
15901            String skipPackages[] = null;
15902            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15903                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15904                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15905                Uri data = intent.getData();
15906                if (data != null) {
15907                    String pkgName = data.getSchemeSpecificPart();
15908                    if (pkgName != null) {
15909                        skipPackages = new String[] { pkgName };
15910                    }
15911                }
15912            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15913                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15914            }
15915            if (skipPackages != null && (skipPackages.length > 0)) {
15916                for (String skipPackage : skipPackages) {
15917                    if (skipPackage != null) {
15918                        int NT = receivers.size();
15919                        for (int it=0; it<NT; it++) {
15920                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15921                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15922                                receivers.remove(it);
15923                                it--;
15924                                NT--;
15925                            }
15926                        }
15927                    }
15928                }
15929            }
15930
15931            int NT = receivers != null ? receivers.size() : 0;
15932            int it = 0;
15933            ResolveInfo curt = null;
15934            BroadcastFilter curr = null;
15935            while (it < NT && ir < NR) {
15936                if (curt == null) {
15937                    curt = (ResolveInfo)receivers.get(it);
15938                }
15939                if (curr == null) {
15940                    curr = registeredReceivers.get(ir);
15941                }
15942                if (curr.getPriority() >= curt.priority) {
15943                    // Insert this broadcast record into the final list.
15944                    receivers.add(it, curr);
15945                    ir++;
15946                    curr = null;
15947                    it++;
15948                    NT++;
15949                } else {
15950                    // Skip to the next ResolveInfo in the final list.
15951                    it++;
15952                    curt = null;
15953                }
15954            }
15955        }
15956        while (ir < NR) {
15957            if (receivers == null) {
15958                receivers = new ArrayList();
15959            }
15960            receivers.add(registeredReceivers.get(ir));
15961            ir++;
15962        }
15963
15964        if ((receivers != null && receivers.size() > 0)
15965                || resultTo != null) {
15966            BroadcastQueue queue = broadcastQueueForIntent(intent);
15967            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15968                    callerPackage, callingPid, callingUid, resolvedType,
15969                    requiredPermission, appOp, receivers, resultTo, resultCode,
15970                    resultData, map, ordered, sticky, false, userId);
15971            if (DEBUG_BROADCAST) Slog.v(
15972                    TAG, "Enqueueing ordered broadcast " + r
15973                    + ": prev had " + queue.mOrderedBroadcasts.size());
15974            if (DEBUG_BROADCAST) {
15975                int seq = r.intent.getIntExtra("seq", -1);
15976                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15977            }
15978            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15979            if (!replaced) {
15980                queue.enqueueOrderedBroadcastLocked(r);
15981                queue.scheduleBroadcastsLocked();
15982            }
15983        }
15984
15985        return ActivityManager.BROADCAST_SUCCESS;
15986    }
15987
15988    final Intent verifyBroadcastLocked(Intent intent) {
15989        // Refuse possible leaked file descriptors
15990        if (intent != null && intent.hasFileDescriptors() == true) {
15991            throw new IllegalArgumentException("File descriptors passed in Intent");
15992        }
15993
15994        int flags = intent.getFlags();
15995
15996        if (!mProcessesReady) {
15997            // if the caller really truly claims to know what they're doing, go
15998            // ahead and allow the broadcast without launching any receivers
15999            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16000                intent = new Intent(intent);
16001                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16002            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16003                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16004                        + " before boot completion");
16005                throw new IllegalStateException("Cannot broadcast before boot completed");
16006            }
16007        }
16008
16009        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16010            throw new IllegalArgumentException(
16011                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16012        }
16013
16014        return intent;
16015    }
16016
16017    public final int broadcastIntent(IApplicationThread caller,
16018            Intent intent, String resolvedType, IIntentReceiver resultTo,
16019            int resultCode, String resultData, Bundle map,
16020            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16021        enforceNotIsolatedCaller("broadcastIntent");
16022        synchronized(this) {
16023            intent = verifyBroadcastLocked(intent);
16024
16025            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16026            final int callingPid = Binder.getCallingPid();
16027            final int callingUid = Binder.getCallingUid();
16028            final long origId = Binder.clearCallingIdentity();
16029            int res = broadcastIntentLocked(callerApp,
16030                    callerApp != null ? callerApp.info.packageName : null,
16031                    intent, resolvedType, resultTo,
16032                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16033                    callingPid, callingUid, userId);
16034            Binder.restoreCallingIdentity(origId);
16035            return res;
16036        }
16037    }
16038
16039    int broadcastIntentInPackage(String packageName, int uid,
16040            Intent intent, String resolvedType, IIntentReceiver resultTo,
16041            int resultCode, String resultData, Bundle map,
16042            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16043        synchronized(this) {
16044            intent = verifyBroadcastLocked(intent);
16045
16046            final long origId = Binder.clearCallingIdentity();
16047            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16048                    resultTo, resultCode, resultData, map, requiredPermission,
16049                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16050            Binder.restoreCallingIdentity(origId);
16051            return res;
16052        }
16053    }
16054
16055    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16056        // Refuse possible leaked file descriptors
16057        if (intent != null && intent.hasFileDescriptors() == true) {
16058            throw new IllegalArgumentException("File descriptors passed in Intent");
16059        }
16060
16061        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16062                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16063
16064        synchronized(this) {
16065            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16066                    != PackageManager.PERMISSION_GRANTED) {
16067                String msg = "Permission Denial: unbroadcastIntent() from pid="
16068                        + Binder.getCallingPid()
16069                        + ", uid=" + Binder.getCallingUid()
16070                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16071                Slog.w(TAG, msg);
16072                throw new SecurityException(msg);
16073            }
16074            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16075            if (stickies != null) {
16076                ArrayList<Intent> list = stickies.get(intent.getAction());
16077                if (list != null) {
16078                    int N = list.size();
16079                    int i;
16080                    for (i=0; i<N; i++) {
16081                        if (intent.filterEquals(list.get(i))) {
16082                            list.remove(i);
16083                            break;
16084                        }
16085                    }
16086                    if (list.size() <= 0) {
16087                        stickies.remove(intent.getAction());
16088                    }
16089                }
16090                if (stickies.size() <= 0) {
16091                    mStickyBroadcasts.remove(userId);
16092                }
16093            }
16094        }
16095    }
16096
16097    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16098            String resultData, Bundle resultExtras, boolean resultAbort) {
16099        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16100        if (r == null) {
16101            Slog.w(TAG, "finishReceiver called but not found on queue");
16102            return false;
16103        }
16104
16105        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16106    }
16107
16108    void backgroundServicesFinishedLocked(int userId) {
16109        for (BroadcastQueue queue : mBroadcastQueues) {
16110            queue.backgroundServicesFinishedLocked(userId);
16111        }
16112    }
16113
16114    public void finishReceiver(IBinder who, int resultCode, String resultData,
16115            Bundle resultExtras, boolean resultAbort) {
16116        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16117
16118        // Refuse possible leaked file descriptors
16119        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16120            throw new IllegalArgumentException("File descriptors passed in Bundle");
16121        }
16122
16123        final long origId = Binder.clearCallingIdentity();
16124        try {
16125            boolean doNext = false;
16126            BroadcastRecord r;
16127
16128            synchronized(this) {
16129                r = broadcastRecordForReceiverLocked(who);
16130                if (r != null) {
16131                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16132                        resultData, resultExtras, resultAbort, true);
16133                }
16134            }
16135
16136            if (doNext) {
16137                r.queue.processNextBroadcast(false);
16138            }
16139            trimApplications();
16140        } finally {
16141            Binder.restoreCallingIdentity(origId);
16142        }
16143    }
16144
16145    // =========================================================
16146    // INSTRUMENTATION
16147    // =========================================================
16148
16149    public boolean startInstrumentation(ComponentName className,
16150            String profileFile, int flags, Bundle arguments,
16151            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16152            int userId, String abiOverride) {
16153        enforceNotIsolatedCaller("startInstrumentation");
16154        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16155                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16156        // Refuse possible leaked file descriptors
16157        if (arguments != null && arguments.hasFileDescriptors()) {
16158            throw new IllegalArgumentException("File descriptors passed in Bundle");
16159        }
16160
16161        synchronized(this) {
16162            InstrumentationInfo ii = null;
16163            ApplicationInfo ai = null;
16164            try {
16165                ii = mContext.getPackageManager().getInstrumentationInfo(
16166                    className, STOCK_PM_FLAGS);
16167                ai = AppGlobals.getPackageManager().getApplicationInfo(
16168                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16169            } catch (PackageManager.NameNotFoundException e) {
16170            } catch (RemoteException e) {
16171            }
16172            if (ii == null) {
16173                reportStartInstrumentationFailure(watcher, className,
16174                        "Unable to find instrumentation info for: " + className);
16175                return false;
16176            }
16177            if (ai == null) {
16178                reportStartInstrumentationFailure(watcher, className,
16179                        "Unable to find instrumentation target package: " + ii.targetPackage);
16180                return false;
16181            }
16182
16183            int match = mContext.getPackageManager().checkSignatures(
16184                    ii.targetPackage, ii.packageName);
16185            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16186                String msg = "Permission Denial: starting instrumentation "
16187                        + className + " from pid="
16188                        + Binder.getCallingPid()
16189                        + ", uid=" + Binder.getCallingPid()
16190                        + " not allowed because package " + ii.packageName
16191                        + " does not have a signature matching the target "
16192                        + ii.targetPackage;
16193                reportStartInstrumentationFailure(watcher, className, msg);
16194                throw new SecurityException(msg);
16195            }
16196
16197            final long origId = Binder.clearCallingIdentity();
16198            // Instrumentation can kill and relaunch even persistent processes
16199            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16200                    "start instr");
16201            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16202            app.instrumentationClass = className;
16203            app.instrumentationInfo = ai;
16204            app.instrumentationProfileFile = profileFile;
16205            app.instrumentationArguments = arguments;
16206            app.instrumentationWatcher = watcher;
16207            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16208            app.instrumentationResultClass = className;
16209            Binder.restoreCallingIdentity(origId);
16210        }
16211
16212        return true;
16213    }
16214
16215    /**
16216     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16217     * error to the logs, but if somebody is watching, send the report there too.  This enables
16218     * the "am" command to report errors with more information.
16219     *
16220     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16221     * @param cn The component name of the instrumentation.
16222     * @param report The error report.
16223     */
16224    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16225            ComponentName cn, String report) {
16226        Slog.w(TAG, report);
16227        try {
16228            if (watcher != null) {
16229                Bundle results = new Bundle();
16230                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16231                results.putString("Error", report);
16232                watcher.instrumentationStatus(cn, -1, results);
16233            }
16234        } catch (RemoteException e) {
16235            Slog.w(TAG, e);
16236        }
16237    }
16238
16239    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16240        if (app.instrumentationWatcher != null) {
16241            try {
16242                // NOTE:  IInstrumentationWatcher *must* be oneway here
16243                app.instrumentationWatcher.instrumentationFinished(
16244                    app.instrumentationClass,
16245                    resultCode,
16246                    results);
16247            } catch (RemoteException e) {
16248            }
16249        }
16250        if (app.instrumentationUiAutomationConnection != null) {
16251            try {
16252                app.instrumentationUiAutomationConnection.shutdown();
16253            } catch (RemoteException re) {
16254                /* ignore */
16255            }
16256            // Only a UiAutomation can set this flag and now that
16257            // it is finished we make sure it is reset to its default.
16258            mUserIsMonkey = false;
16259        }
16260        app.instrumentationWatcher = null;
16261        app.instrumentationUiAutomationConnection = null;
16262        app.instrumentationClass = null;
16263        app.instrumentationInfo = null;
16264        app.instrumentationProfileFile = null;
16265        app.instrumentationArguments = null;
16266
16267        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16268                "finished inst");
16269    }
16270
16271    public void finishInstrumentation(IApplicationThread target,
16272            int resultCode, Bundle results) {
16273        int userId = UserHandle.getCallingUserId();
16274        // Refuse possible leaked file descriptors
16275        if (results != null && results.hasFileDescriptors()) {
16276            throw new IllegalArgumentException("File descriptors passed in Intent");
16277        }
16278
16279        synchronized(this) {
16280            ProcessRecord app = getRecordForAppLocked(target);
16281            if (app == null) {
16282                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16283                return;
16284            }
16285            final long origId = Binder.clearCallingIdentity();
16286            finishInstrumentationLocked(app, resultCode, results);
16287            Binder.restoreCallingIdentity(origId);
16288        }
16289    }
16290
16291    // =========================================================
16292    // CONFIGURATION
16293    // =========================================================
16294
16295    public ConfigurationInfo getDeviceConfigurationInfo() {
16296        ConfigurationInfo config = new ConfigurationInfo();
16297        synchronized (this) {
16298            config.reqTouchScreen = mConfiguration.touchscreen;
16299            config.reqKeyboardType = mConfiguration.keyboard;
16300            config.reqNavigation = mConfiguration.navigation;
16301            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16302                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16303                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16304            }
16305            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16306                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16307                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16308            }
16309            config.reqGlEsVersion = GL_ES_VERSION;
16310        }
16311        return config;
16312    }
16313
16314    ActivityStack getFocusedStack() {
16315        return mStackSupervisor.getFocusedStack();
16316    }
16317
16318    public Configuration getConfiguration() {
16319        Configuration ci;
16320        synchronized(this) {
16321            ci = new Configuration(mConfiguration);
16322        }
16323        return ci;
16324    }
16325
16326    public void updatePersistentConfiguration(Configuration values) {
16327        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16328                "updateConfiguration()");
16329        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16330                "updateConfiguration()");
16331        if (values == null) {
16332            throw new NullPointerException("Configuration must not be null");
16333        }
16334
16335        synchronized(this) {
16336            final long origId = Binder.clearCallingIdentity();
16337            updateConfigurationLocked(values, null, true, false);
16338            Binder.restoreCallingIdentity(origId);
16339        }
16340    }
16341
16342    public void updateConfiguration(Configuration values) {
16343        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16344                "updateConfiguration()");
16345
16346        synchronized(this) {
16347            if (values == null && mWindowManager != null) {
16348                // sentinel: fetch the current configuration from the window manager
16349                values = mWindowManager.computeNewConfiguration();
16350            }
16351
16352            if (mWindowManager != null) {
16353                mProcessList.applyDisplaySize(mWindowManager);
16354            }
16355
16356            final long origId = Binder.clearCallingIdentity();
16357            if (values != null) {
16358                Settings.System.clearConfiguration(values);
16359            }
16360            updateConfigurationLocked(values, null, false, false);
16361            Binder.restoreCallingIdentity(origId);
16362        }
16363    }
16364
16365    /**
16366     * Do either or both things: (1) change the current configuration, and (2)
16367     * make sure the given activity is running with the (now) current
16368     * configuration.  Returns true if the activity has been left running, or
16369     * false if <var>starting</var> is being destroyed to match the new
16370     * configuration.
16371     * @param persistent TODO
16372     */
16373    boolean updateConfigurationLocked(Configuration values,
16374            ActivityRecord starting, boolean persistent, boolean initLocale) {
16375        int changes = 0;
16376
16377        if (values != null) {
16378            Configuration newConfig = new Configuration(mConfiguration);
16379            changes = newConfig.updateFrom(values);
16380            if (changes != 0) {
16381                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16382                    Slog.i(TAG, "Updating configuration to: " + values);
16383                }
16384
16385                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16386
16387                if (values.locale != null && !initLocale) {
16388                    saveLocaleLocked(values.locale,
16389                                     !values.locale.equals(mConfiguration.locale),
16390                                     values.userSetLocale);
16391                }
16392
16393                mConfigurationSeq++;
16394                if (mConfigurationSeq <= 0) {
16395                    mConfigurationSeq = 1;
16396                }
16397                newConfig.seq = mConfigurationSeq;
16398                mConfiguration = newConfig;
16399                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16400                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16401                //mUsageStatsService.noteStartConfig(newConfig);
16402
16403                final Configuration configCopy = new Configuration(mConfiguration);
16404
16405                // TODO: If our config changes, should we auto dismiss any currently
16406                // showing dialogs?
16407                mShowDialogs = shouldShowDialogs(newConfig);
16408
16409                AttributeCache ac = AttributeCache.instance();
16410                if (ac != null) {
16411                    ac.updateConfiguration(configCopy);
16412                }
16413
16414                // Make sure all resources in our process are updated
16415                // right now, so that anyone who is going to retrieve
16416                // resource values after we return will be sure to get
16417                // the new ones.  This is especially important during
16418                // boot, where the first config change needs to guarantee
16419                // all resources have that config before following boot
16420                // code is executed.
16421                mSystemThread.applyConfigurationToResources(configCopy);
16422
16423                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16424                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16425                    msg.obj = new Configuration(configCopy);
16426                    mHandler.sendMessage(msg);
16427                }
16428
16429                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16430                    ProcessRecord app = mLruProcesses.get(i);
16431                    try {
16432                        if (app.thread != null) {
16433                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16434                                    + app.processName + " new config " + mConfiguration);
16435                            app.thread.scheduleConfigurationChanged(configCopy);
16436                        }
16437                    } catch (Exception e) {
16438                    }
16439                }
16440                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16441                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16442                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16443                        | Intent.FLAG_RECEIVER_FOREGROUND);
16444                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16445                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16446                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16447                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16448                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16449                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16450                    broadcastIntentLocked(null, null, intent,
16451                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16452                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16453                }
16454            }
16455        }
16456
16457        boolean kept = true;
16458        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16459        // mainStack is null during startup.
16460        if (mainStack != null) {
16461            if (changes != 0 && starting == null) {
16462                // If the configuration changed, and the caller is not already
16463                // in the process of starting an activity, then find the top
16464                // activity to check if its configuration needs to change.
16465                starting = mainStack.topRunningActivityLocked(null);
16466            }
16467
16468            if (starting != null) {
16469                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16470                // And we need to make sure at this point that all other activities
16471                // are made visible with the correct configuration.
16472                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16473            }
16474        }
16475
16476        if (values != null && mWindowManager != null) {
16477            mWindowManager.setNewConfiguration(mConfiguration);
16478        }
16479
16480        return kept;
16481    }
16482
16483    /**
16484     * Decide based on the configuration whether we should shouw the ANR,
16485     * crash, etc dialogs.  The idea is that if there is no affordnace to
16486     * press the on-screen buttons, we shouldn't show the dialog.
16487     *
16488     * A thought: SystemUI might also want to get told about this, the Power
16489     * dialog / global actions also might want different behaviors.
16490     */
16491    private static final boolean shouldShowDialogs(Configuration config) {
16492        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16493                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16494    }
16495
16496    /**
16497     * Save the locale.  You must be inside a synchronized (this) block.
16498     */
16499    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16500        if(isDiff) {
16501            SystemProperties.set("user.language", l.getLanguage());
16502            SystemProperties.set("user.region", l.getCountry());
16503        }
16504
16505        if(isPersist) {
16506            SystemProperties.set("persist.sys.language", l.getLanguage());
16507            SystemProperties.set("persist.sys.country", l.getCountry());
16508            SystemProperties.set("persist.sys.localevar", l.getVariant());
16509
16510            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16511        }
16512    }
16513
16514    @Override
16515    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16516        synchronized (this) {
16517            ActivityRecord srec = ActivityRecord.forToken(token);
16518            if (srec.task != null && srec.task.stack != null) {
16519                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16520            }
16521        }
16522        return false;
16523    }
16524
16525    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16526            Intent resultData) {
16527
16528        synchronized (this) {
16529            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16530            if (stack != null) {
16531                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16532            }
16533            return false;
16534        }
16535    }
16536
16537    public int getLaunchedFromUid(IBinder activityToken) {
16538        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16539        if (srec == null) {
16540            return -1;
16541        }
16542        return srec.launchedFromUid;
16543    }
16544
16545    public String getLaunchedFromPackage(IBinder activityToken) {
16546        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16547        if (srec == null) {
16548            return null;
16549        }
16550        return srec.launchedFromPackage;
16551    }
16552
16553    // =========================================================
16554    // LIFETIME MANAGEMENT
16555    // =========================================================
16556
16557    // Returns which broadcast queue the app is the current [or imminent] receiver
16558    // on, or 'null' if the app is not an active broadcast recipient.
16559    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16560        BroadcastRecord r = app.curReceiver;
16561        if (r != null) {
16562            return r.queue;
16563        }
16564
16565        // It's not the current receiver, but it might be starting up to become one
16566        synchronized (this) {
16567            for (BroadcastQueue queue : mBroadcastQueues) {
16568                r = queue.mPendingBroadcast;
16569                if (r != null && r.curApp == app) {
16570                    // found it; report which queue it's in
16571                    return queue;
16572                }
16573            }
16574        }
16575
16576        return null;
16577    }
16578
16579    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16580            boolean doingAll, long now) {
16581        if (mAdjSeq == app.adjSeq) {
16582            // This adjustment has already been computed.
16583            return app.curRawAdj;
16584        }
16585
16586        if (app.thread == null) {
16587            app.adjSeq = mAdjSeq;
16588            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16589            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16590            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16591        }
16592
16593        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16594        app.adjSource = null;
16595        app.adjTarget = null;
16596        app.empty = false;
16597        app.cached = false;
16598
16599        final int activitiesSize = app.activities.size();
16600
16601        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16602            // The max adjustment doesn't allow this app to be anything
16603            // below foreground, so it is not worth doing work for it.
16604            app.adjType = "fixed";
16605            app.adjSeq = mAdjSeq;
16606            app.curRawAdj = app.maxAdj;
16607            app.foregroundActivities = false;
16608            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16609            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16610            // System processes can do UI, and when they do we want to have
16611            // them trim their memory after the user leaves the UI.  To
16612            // facilitate this, here we need to determine whether or not it
16613            // is currently showing UI.
16614            app.systemNoUi = true;
16615            if (app == TOP_APP) {
16616                app.systemNoUi = false;
16617            } else if (activitiesSize > 0) {
16618                for (int j = 0; j < activitiesSize; j++) {
16619                    final ActivityRecord r = app.activities.get(j);
16620                    if (r.visible) {
16621                        app.systemNoUi = false;
16622                    }
16623                }
16624            }
16625            if (!app.systemNoUi) {
16626                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16627            }
16628            return (app.curAdj=app.maxAdj);
16629        }
16630
16631        app.systemNoUi = false;
16632
16633        // Determine the importance of the process, starting with most
16634        // important to least, and assign an appropriate OOM adjustment.
16635        int adj;
16636        int schedGroup;
16637        int procState;
16638        boolean foregroundActivities = false;
16639        BroadcastQueue queue;
16640        if (app == TOP_APP) {
16641            // The last app on the list is the foreground app.
16642            adj = ProcessList.FOREGROUND_APP_ADJ;
16643            schedGroup = Process.THREAD_GROUP_DEFAULT;
16644            app.adjType = "top-activity";
16645            foregroundActivities = true;
16646            procState = ActivityManager.PROCESS_STATE_TOP;
16647        } else if (app.instrumentationClass != null) {
16648            // Don't want to kill running instrumentation.
16649            adj = ProcessList.FOREGROUND_APP_ADJ;
16650            schedGroup = Process.THREAD_GROUP_DEFAULT;
16651            app.adjType = "instrumentation";
16652            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16653        } else if ((queue = isReceivingBroadcast(app)) != null) {
16654            // An app that is currently receiving a broadcast also
16655            // counts as being in the foreground for OOM killer purposes.
16656            // It's placed in a sched group based on the nature of the
16657            // broadcast as reflected by which queue it's active in.
16658            adj = ProcessList.FOREGROUND_APP_ADJ;
16659            schedGroup = (queue == mFgBroadcastQueue)
16660                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16661            app.adjType = "broadcast";
16662            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16663        } else if (app.executingServices.size() > 0) {
16664            // An app that is currently executing a service callback also
16665            // counts as being in the foreground.
16666            adj = ProcessList.FOREGROUND_APP_ADJ;
16667            schedGroup = app.execServicesFg ?
16668                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16669            app.adjType = "exec-service";
16670            procState = ActivityManager.PROCESS_STATE_SERVICE;
16671            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16672        } else {
16673            // As far as we know the process is empty.  We may change our mind later.
16674            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16675            // At this point we don't actually know the adjustment.  Use the cached adj
16676            // value that the caller wants us to.
16677            adj = cachedAdj;
16678            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16679            app.cached = true;
16680            app.empty = true;
16681            app.adjType = "cch-empty";
16682        }
16683
16684        // Examine all activities if not already foreground.
16685        if (!foregroundActivities && activitiesSize > 0) {
16686            for (int j = 0; j < activitiesSize; j++) {
16687                final ActivityRecord r = app.activities.get(j);
16688                if (r.app != app) {
16689                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16690                            + app + "?!?");
16691                    continue;
16692                }
16693                if (r.visible) {
16694                    // App has a visible activity; only upgrade adjustment.
16695                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16696                        adj = ProcessList.VISIBLE_APP_ADJ;
16697                        app.adjType = "visible";
16698                    }
16699                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16700                        procState = ActivityManager.PROCESS_STATE_TOP;
16701                    }
16702                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16703                    app.cached = false;
16704                    app.empty = false;
16705                    foregroundActivities = true;
16706                    break;
16707                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16708                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16709                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16710                        app.adjType = "pausing";
16711                    }
16712                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16713                        procState = ActivityManager.PROCESS_STATE_TOP;
16714                    }
16715                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16716                    app.cached = false;
16717                    app.empty = false;
16718                    foregroundActivities = true;
16719                } else if (r.state == ActivityState.STOPPING) {
16720                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16721                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16722                        app.adjType = "stopping";
16723                    }
16724                    // For the process state, we will at this point consider the
16725                    // process to be cached.  It will be cached either as an activity
16726                    // or empty depending on whether the activity is finishing.  We do
16727                    // this so that we can treat the process as cached for purposes of
16728                    // memory trimming (determing current memory level, trim command to
16729                    // send to process) since there can be an arbitrary number of stopping
16730                    // processes and they should soon all go into the cached state.
16731                    if (!r.finishing) {
16732                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16733                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16734                        }
16735                    }
16736                    app.cached = false;
16737                    app.empty = false;
16738                    foregroundActivities = true;
16739                } else {
16740                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16741                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16742                        app.adjType = "cch-act";
16743                    }
16744                }
16745            }
16746        }
16747
16748        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16749            if (app.foregroundServices) {
16750                // The user is aware of this app, so make it visible.
16751                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16752                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16753                app.cached = false;
16754                app.adjType = "fg-service";
16755                schedGroup = Process.THREAD_GROUP_DEFAULT;
16756            } else if (app.forcingToForeground != null) {
16757                // The user is aware of this app, so make it visible.
16758                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16759                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16760                app.cached = false;
16761                app.adjType = "force-fg";
16762                app.adjSource = app.forcingToForeground;
16763                schedGroup = Process.THREAD_GROUP_DEFAULT;
16764            }
16765        }
16766
16767        if (app == mHeavyWeightProcess) {
16768            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16769                // We don't want to kill the current heavy-weight process.
16770                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16771                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16772                app.cached = false;
16773                app.adjType = "heavy";
16774            }
16775            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16776                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16777            }
16778        }
16779
16780        if (app == mHomeProcess) {
16781            if (adj > ProcessList.HOME_APP_ADJ) {
16782                // This process is hosting what we currently consider to be the
16783                // home app, so we don't want to let it go into the background.
16784                adj = ProcessList.HOME_APP_ADJ;
16785                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16786                app.cached = false;
16787                app.adjType = "home";
16788            }
16789            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16790                procState = ActivityManager.PROCESS_STATE_HOME;
16791            }
16792        }
16793
16794        if (app == mPreviousProcess && app.activities.size() > 0) {
16795            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16796                // This was the previous process that showed UI to the user.
16797                // We want to try to keep it around more aggressively, to give
16798                // a good experience around switching between two apps.
16799                adj = ProcessList.PREVIOUS_APP_ADJ;
16800                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16801                app.cached = false;
16802                app.adjType = "previous";
16803            }
16804            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16805                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16806            }
16807        }
16808
16809        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16810                + " reason=" + app.adjType);
16811
16812        // By default, we use the computed adjustment.  It may be changed if
16813        // there are applications dependent on our services or providers, but
16814        // this gives us a baseline and makes sure we don't get into an
16815        // infinite recursion.
16816        app.adjSeq = mAdjSeq;
16817        app.curRawAdj = adj;
16818        app.hasStartedServices = false;
16819
16820        if (mBackupTarget != null && app == mBackupTarget.app) {
16821            // If possible we want to avoid killing apps while they're being backed up
16822            if (adj > ProcessList.BACKUP_APP_ADJ) {
16823                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16824                adj = ProcessList.BACKUP_APP_ADJ;
16825                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16826                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16827                }
16828                app.adjType = "backup";
16829                app.cached = false;
16830            }
16831            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16832                procState = ActivityManager.PROCESS_STATE_BACKUP;
16833            }
16834        }
16835
16836        boolean mayBeTop = false;
16837
16838        for (int is = app.services.size()-1;
16839                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16840                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16841                        || procState > ActivityManager.PROCESS_STATE_TOP);
16842                is--) {
16843            ServiceRecord s = app.services.valueAt(is);
16844            if (s.startRequested) {
16845                app.hasStartedServices = true;
16846                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16847                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16848                }
16849                if (app.hasShownUi && app != mHomeProcess) {
16850                    // If this process has shown some UI, let it immediately
16851                    // go to the LRU list because it may be pretty heavy with
16852                    // UI stuff.  We'll tag it with a label just to help
16853                    // debug and understand what is going on.
16854                    if (adj > ProcessList.SERVICE_ADJ) {
16855                        app.adjType = "cch-started-ui-services";
16856                    }
16857                } else {
16858                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16859                        // This service has seen some activity within
16860                        // recent memory, so we will keep its process ahead
16861                        // of the background processes.
16862                        if (adj > ProcessList.SERVICE_ADJ) {
16863                            adj = ProcessList.SERVICE_ADJ;
16864                            app.adjType = "started-services";
16865                            app.cached = false;
16866                        }
16867                    }
16868                    // If we have let the service slide into the background
16869                    // state, still have some text describing what it is doing
16870                    // even though the service no longer has an impact.
16871                    if (adj > ProcessList.SERVICE_ADJ) {
16872                        app.adjType = "cch-started-services";
16873                    }
16874                }
16875            }
16876            for (int conni = s.connections.size()-1;
16877                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16878                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16879                            || procState > ActivityManager.PROCESS_STATE_TOP);
16880                    conni--) {
16881                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16882                for (int i = 0;
16883                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16884                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16885                                || procState > ActivityManager.PROCESS_STATE_TOP);
16886                        i++) {
16887                    // XXX should compute this based on the max of
16888                    // all connected clients.
16889                    ConnectionRecord cr = clist.get(i);
16890                    if (cr.binding.client == app) {
16891                        // Binding to ourself is not interesting.
16892                        continue;
16893                    }
16894                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16895                        ProcessRecord client = cr.binding.client;
16896                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16897                                TOP_APP, doingAll, now);
16898                        int clientProcState = client.curProcState;
16899                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16900                            // If the other app is cached for any reason, for purposes here
16901                            // we are going to consider it empty.  The specific cached state
16902                            // doesn't propagate except under certain conditions.
16903                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16904                        }
16905                        String adjType = null;
16906                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16907                            // Not doing bind OOM management, so treat
16908                            // this guy more like a started service.
16909                            if (app.hasShownUi && app != mHomeProcess) {
16910                                // If this process has shown some UI, let it immediately
16911                                // go to the LRU list because it may be pretty heavy with
16912                                // UI stuff.  We'll tag it with a label just to help
16913                                // debug and understand what is going on.
16914                                if (adj > clientAdj) {
16915                                    adjType = "cch-bound-ui-services";
16916                                }
16917                                app.cached = false;
16918                                clientAdj = adj;
16919                                clientProcState = procState;
16920                            } else {
16921                                if (now >= (s.lastActivity
16922                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16923                                    // This service has not seen activity within
16924                                    // recent memory, so allow it to drop to the
16925                                    // LRU list if there is no other reason to keep
16926                                    // it around.  We'll also tag it with a label just
16927                                    // to help debug and undertand what is going on.
16928                                    if (adj > clientAdj) {
16929                                        adjType = "cch-bound-services";
16930                                    }
16931                                    clientAdj = adj;
16932                                }
16933                            }
16934                        }
16935                        if (adj > clientAdj) {
16936                            // If this process has recently shown UI, and
16937                            // the process that is binding to it is less
16938                            // important than being visible, then we don't
16939                            // care about the binding as much as we care
16940                            // about letting this process get into the LRU
16941                            // list to be killed and restarted if needed for
16942                            // memory.
16943                            if (app.hasShownUi && app != mHomeProcess
16944                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16945                                adjType = "cch-bound-ui-services";
16946                            } else {
16947                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16948                                        |Context.BIND_IMPORTANT)) != 0) {
16949                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16950                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16951                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16952                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16953                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16954                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16955                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16956                                    adj = clientAdj;
16957                                } else {
16958                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16959                                        adj = ProcessList.VISIBLE_APP_ADJ;
16960                                    }
16961                                }
16962                                if (!client.cached) {
16963                                    app.cached = false;
16964                                }
16965                                adjType = "service";
16966                            }
16967                        }
16968                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16969                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16970                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16971                            }
16972                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16973                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16974                                    // Special handling of clients who are in the top state.
16975                                    // We *may* want to consider this process to be in the
16976                                    // top state as well, but only if there is not another
16977                                    // reason for it to be running.  Being on the top is a
16978                                    // special state, meaning you are specifically running
16979                                    // for the current top app.  If the process is already
16980                                    // running in the background for some other reason, it
16981                                    // is more important to continue considering it to be
16982                                    // in the background state.
16983                                    mayBeTop = true;
16984                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16985                                } else {
16986                                    // Special handling for above-top states (persistent
16987                                    // processes).  These should not bring the current process
16988                                    // into the top state, since they are not on top.  Instead
16989                                    // give them the best state after that.
16990                                    clientProcState =
16991                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16992                                }
16993                            }
16994                        } else {
16995                            if (clientProcState <
16996                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16997                                clientProcState =
16998                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16999                            }
17000                        }
17001                        if (procState > clientProcState) {
17002                            procState = clientProcState;
17003                        }
17004                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17005                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17006                            app.pendingUiClean = true;
17007                        }
17008                        if (adjType != null) {
17009                            app.adjType = adjType;
17010                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17011                                    .REASON_SERVICE_IN_USE;
17012                            app.adjSource = cr.binding.client;
17013                            app.adjSourceProcState = clientProcState;
17014                            app.adjTarget = s.name;
17015                        }
17016                    }
17017                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17018                        app.treatLikeActivity = true;
17019                    }
17020                    final ActivityRecord a = cr.activity;
17021                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17022                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17023                                (a.visible || a.state == ActivityState.RESUMED
17024                                 || a.state == ActivityState.PAUSING)) {
17025                            adj = ProcessList.FOREGROUND_APP_ADJ;
17026                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17027                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17028                            }
17029                            app.cached = false;
17030                            app.adjType = "service";
17031                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17032                                    .REASON_SERVICE_IN_USE;
17033                            app.adjSource = a;
17034                            app.adjSourceProcState = procState;
17035                            app.adjTarget = s.name;
17036                        }
17037                    }
17038                }
17039            }
17040        }
17041
17042        for (int provi = app.pubProviders.size()-1;
17043                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17044                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17045                        || procState > ActivityManager.PROCESS_STATE_TOP);
17046                provi--) {
17047            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17048            for (int i = cpr.connections.size()-1;
17049                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17050                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17051                            || procState > ActivityManager.PROCESS_STATE_TOP);
17052                    i--) {
17053                ContentProviderConnection conn = cpr.connections.get(i);
17054                ProcessRecord client = conn.client;
17055                if (client == app) {
17056                    // Being our own client is not interesting.
17057                    continue;
17058                }
17059                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17060                int clientProcState = client.curProcState;
17061                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17062                    // If the other app is cached for any reason, for purposes here
17063                    // we are going to consider it empty.
17064                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17065                }
17066                if (adj > clientAdj) {
17067                    if (app.hasShownUi && app != mHomeProcess
17068                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17069                        app.adjType = "cch-ui-provider";
17070                    } else {
17071                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17072                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17073                        app.adjType = "provider";
17074                    }
17075                    app.cached &= client.cached;
17076                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17077                            .REASON_PROVIDER_IN_USE;
17078                    app.adjSource = client;
17079                    app.adjSourceProcState = clientProcState;
17080                    app.adjTarget = cpr.name;
17081                }
17082                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17083                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17084                        // Special handling of clients who are in the top state.
17085                        // We *may* want to consider this process to be in the
17086                        // top state as well, but only if there is not another
17087                        // reason for it to be running.  Being on the top is a
17088                        // special state, meaning you are specifically running
17089                        // for the current top app.  If the process is already
17090                        // running in the background for some other reason, it
17091                        // is more important to continue considering it to be
17092                        // in the background state.
17093                        mayBeTop = true;
17094                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17095                    } else {
17096                        // Special handling for above-top states (persistent
17097                        // processes).  These should not bring the current process
17098                        // into the top state, since they are not on top.  Instead
17099                        // give them the best state after that.
17100                        clientProcState =
17101                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17102                    }
17103                }
17104                if (procState > clientProcState) {
17105                    procState = clientProcState;
17106                }
17107                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17108                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17109                }
17110            }
17111            // If the provider has external (non-framework) process
17112            // dependencies, ensure that its adjustment is at least
17113            // FOREGROUND_APP_ADJ.
17114            if (cpr.hasExternalProcessHandles()) {
17115                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17116                    adj = ProcessList.FOREGROUND_APP_ADJ;
17117                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17118                    app.cached = false;
17119                    app.adjType = "provider";
17120                    app.adjTarget = cpr.name;
17121                }
17122                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17123                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17124                }
17125            }
17126        }
17127
17128        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17129            // A client of one of our services or providers is in the top state.  We
17130            // *may* want to be in the top state, but not if we are already running in
17131            // the background for some other reason.  For the decision here, we are going
17132            // to pick out a few specific states that we want to remain in when a client
17133            // is top (states that tend to be longer-term) and otherwise allow it to go
17134            // to the top state.
17135            switch (procState) {
17136                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17137                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17138                case ActivityManager.PROCESS_STATE_SERVICE:
17139                    // These all are longer-term states, so pull them up to the top
17140                    // of the background states, but not all the way to the top state.
17141                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17142                    break;
17143                default:
17144                    // Otherwise, top is a better choice, so take it.
17145                    procState = ActivityManager.PROCESS_STATE_TOP;
17146                    break;
17147            }
17148        }
17149
17150        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17151            if (app.hasClientActivities) {
17152                // This is a cached process, but with client activities.  Mark it so.
17153                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17154                app.adjType = "cch-client-act";
17155            } else if (app.treatLikeActivity) {
17156                // This is a cached process, but somebody wants us to treat it like it has
17157                // an activity, okay!
17158                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17159                app.adjType = "cch-as-act";
17160            }
17161        }
17162
17163        if (adj == ProcessList.SERVICE_ADJ) {
17164            if (doingAll) {
17165                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17166                mNewNumServiceProcs++;
17167                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17168                if (!app.serviceb) {
17169                    // This service isn't far enough down on the LRU list to
17170                    // normally be a B service, but if we are low on RAM and it
17171                    // is large we want to force it down since we would prefer to
17172                    // keep launcher over it.
17173                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17174                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17175                        app.serviceHighRam = true;
17176                        app.serviceb = true;
17177                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17178                    } else {
17179                        mNewNumAServiceProcs++;
17180                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17181                    }
17182                } else {
17183                    app.serviceHighRam = false;
17184                }
17185            }
17186            if (app.serviceb) {
17187                adj = ProcessList.SERVICE_B_ADJ;
17188            }
17189        }
17190
17191        app.curRawAdj = adj;
17192
17193        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17194        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17195        if (adj > app.maxAdj) {
17196            adj = app.maxAdj;
17197            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17198                schedGroup = Process.THREAD_GROUP_DEFAULT;
17199            }
17200        }
17201
17202        // Do final modification to adj.  Everything we do between here and applying
17203        // the final setAdj must be done in this function, because we will also use
17204        // it when computing the final cached adj later.  Note that we don't need to
17205        // worry about this for max adj above, since max adj will always be used to
17206        // keep it out of the cached vaues.
17207        app.curAdj = app.modifyRawOomAdj(adj);
17208        app.curSchedGroup = schedGroup;
17209        app.curProcState = procState;
17210        app.foregroundActivities = foregroundActivities;
17211
17212        return app.curRawAdj;
17213    }
17214
17215    /**
17216     * Schedule PSS collection of a process.
17217     */
17218    void requestPssLocked(ProcessRecord proc, int procState) {
17219        if (mPendingPssProcesses.contains(proc)) {
17220            return;
17221        }
17222        if (mPendingPssProcesses.size() == 0) {
17223            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17224        }
17225        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17226        proc.pssProcState = procState;
17227        mPendingPssProcesses.add(proc);
17228    }
17229
17230    /**
17231     * Schedule PSS collection of all processes.
17232     */
17233    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17234        if (!always) {
17235            if (now < (mLastFullPssTime +
17236                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17237                return;
17238            }
17239        }
17240        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17241        mLastFullPssTime = now;
17242        mFullPssPending = true;
17243        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17244        mPendingPssProcesses.clear();
17245        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17246            ProcessRecord app = mLruProcesses.get(i);
17247            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17248                app.pssProcState = app.setProcState;
17249                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17250                        isSleeping(), now);
17251                mPendingPssProcesses.add(app);
17252            }
17253        }
17254        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17255    }
17256
17257    /**
17258     * Ask a given process to GC right now.
17259     */
17260    final void performAppGcLocked(ProcessRecord app) {
17261        try {
17262            app.lastRequestedGc = SystemClock.uptimeMillis();
17263            if (app.thread != null) {
17264                if (app.reportLowMemory) {
17265                    app.reportLowMemory = false;
17266                    app.thread.scheduleLowMemory();
17267                } else {
17268                    app.thread.processInBackground();
17269                }
17270            }
17271        } catch (Exception e) {
17272            // whatever.
17273        }
17274    }
17275
17276    /**
17277     * Returns true if things are idle enough to perform GCs.
17278     */
17279    private final boolean canGcNowLocked() {
17280        boolean processingBroadcasts = false;
17281        for (BroadcastQueue q : mBroadcastQueues) {
17282            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17283                processingBroadcasts = true;
17284            }
17285        }
17286        return !processingBroadcasts
17287                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17288    }
17289
17290    /**
17291     * Perform GCs on all processes that are waiting for it, but only
17292     * if things are idle.
17293     */
17294    final void performAppGcsLocked() {
17295        final int N = mProcessesToGc.size();
17296        if (N <= 0) {
17297            return;
17298        }
17299        if (canGcNowLocked()) {
17300            while (mProcessesToGc.size() > 0) {
17301                ProcessRecord proc = mProcessesToGc.remove(0);
17302                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17303                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17304                            <= SystemClock.uptimeMillis()) {
17305                        // To avoid spamming the system, we will GC processes one
17306                        // at a time, waiting a few seconds between each.
17307                        performAppGcLocked(proc);
17308                        scheduleAppGcsLocked();
17309                        return;
17310                    } else {
17311                        // It hasn't been long enough since we last GCed this
17312                        // process...  put it in the list to wait for its time.
17313                        addProcessToGcListLocked(proc);
17314                        break;
17315                    }
17316                }
17317            }
17318
17319            scheduleAppGcsLocked();
17320        }
17321    }
17322
17323    /**
17324     * If all looks good, perform GCs on all processes waiting for them.
17325     */
17326    final void performAppGcsIfAppropriateLocked() {
17327        if (canGcNowLocked()) {
17328            performAppGcsLocked();
17329            return;
17330        }
17331        // Still not idle, wait some more.
17332        scheduleAppGcsLocked();
17333    }
17334
17335    /**
17336     * Schedule the execution of all pending app GCs.
17337     */
17338    final void scheduleAppGcsLocked() {
17339        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17340
17341        if (mProcessesToGc.size() > 0) {
17342            // Schedule a GC for the time to the next process.
17343            ProcessRecord proc = mProcessesToGc.get(0);
17344            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17345
17346            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17347            long now = SystemClock.uptimeMillis();
17348            if (when < (now+GC_TIMEOUT)) {
17349                when = now + GC_TIMEOUT;
17350            }
17351            mHandler.sendMessageAtTime(msg, when);
17352        }
17353    }
17354
17355    /**
17356     * Add a process to the array of processes waiting to be GCed.  Keeps the
17357     * list in sorted order by the last GC time.  The process can't already be
17358     * on the list.
17359     */
17360    final void addProcessToGcListLocked(ProcessRecord proc) {
17361        boolean added = false;
17362        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17363            if (mProcessesToGc.get(i).lastRequestedGc <
17364                    proc.lastRequestedGc) {
17365                added = true;
17366                mProcessesToGc.add(i+1, proc);
17367                break;
17368            }
17369        }
17370        if (!added) {
17371            mProcessesToGc.add(0, proc);
17372        }
17373    }
17374
17375    /**
17376     * Set up to ask a process to GC itself.  This will either do it
17377     * immediately, or put it on the list of processes to gc the next
17378     * time things are idle.
17379     */
17380    final void scheduleAppGcLocked(ProcessRecord app) {
17381        long now = SystemClock.uptimeMillis();
17382        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17383            return;
17384        }
17385        if (!mProcessesToGc.contains(app)) {
17386            addProcessToGcListLocked(app);
17387            scheduleAppGcsLocked();
17388        }
17389    }
17390
17391    final void checkExcessivePowerUsageLocked(boolean doKills) {
17392        updateCpuStatsNow();
17393
17394        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17395        boolean doWakeKills = doKills;
17396        boolean doCpuKills = doKills;
17397        if (mLastPowerCheckRealtime == 0) {
17398            doWakeKills = false;
17399        }
17400        if (mLastPowerCheckUptime == 0) {
17401            doCpuKills = false;
17402        }
17403        if (stats.isScreenOn()) {
17404            doWakeKills = false;
17405        }
17406        final long curRealtime = SystemClock.elapsedRealtime();
17407        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17408        final long curUptime = SystemClock.uptimeMillis();
17409        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17410        mLastPowerCheckRealtime = curRealtime;
17411        mLastPowerCheckUptime = curUptime;
17412        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17413            doWakeKills = false;
17414        }
17415        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17416            doCpuKills = false;
17417        }
17418        int i = mLruProcesses.size();
17419        while (i > 0) {
17420            i--;
17421            ProcessRecord app = mLruProcesses.get(i);
17422            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17423                long wtime;
17424                synchronized (stats) {
17425                    wtime = stats.getProcessWakeTime(app.info.uid,
17426                            app.pid, curRealtime);
17427                }
17428                long wtimeUsed = wtime - app.lastWakeTime;
17429                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17430                if (DEBUG_POWER) {
17431                    StringBuilder sb = new StringBuilder(128);
17432                    sb.append("Wake for ");
17433                    app.toShortString(sb);
17434                    sb.append(": over ");
17435                    TimeUtils.formatDuration(realtimeSince, sb);
17436                    sb.append(" used ");
17437                    TimeUtils.formatDuration(wtimeUsed, sb);
17438                    sb.append(" (");
17439                    sb.append((wtimeUsed*100)/realtimeSince);
17440                    sb.append("%)");
17441                    Slog.i(TAG, sb.toString());
17442                    sb.setLength(0);
17443                    sb.append("CPU for ");
17444                    app.toShortString(sb);
17445                    sb.append(": over ");
17446                    TimeUtils.formatDuration(uptimeSince, sb);
17447                    sb.append(" used ");
17448                    TimeUtils.formatDuration(cputimeUsed, sb);
17449                    sb.append(" (");
17450                    sb.append((cputimeUsed*100)/uptimeSince);
17451                    sb.append("%)");
17452                    Slog.i(TAG, sb.toString());
17453                }
17454                // If a process has held a wake lock for more
17455                // than 50% of the time during this period,
17456                // that sounds bad.  Kill!
17457                if (doWakeKills && realtimeSince > 0
17458                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17459                    synchronized (stats) {
17460                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17461                                realtimeSince, wtimeUsed);
17462                    }
17463                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17464                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17465                } else if (doCpuKills && uptimeSince > 0
17466                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17467                    synchronized (stats) {
17468                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17469                                uptimeSince, cputimeUsed);
17470                    }
17471                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17472                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17473                } else {
17474                    app.lastWakeTime = wtime;
17475                    app.lastCpuTime = app.curCpuTime;
17476                }
17477            }
17478        }
17479    }
17480
17481    private final boolean applyOomAdjLocked(ProcessRecord app,
17482            ProcessRecord TOP_APP, boolean doingAll, long now) {
17483        boolean success = true;
17484
17485        if (app.curRawAdj != app.setRawAdj) {
17486            app.setRawAdj = app.curRawAdj;
17487        }
17488
17489        int changes = 0;
17490
17491        if (app.curAdj != app.setAdj) {
17492            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17493            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17494                TAG, "Set " + app.pid + " " + app.processName +
17495                " adj " + app.curAdj + ": " + app.adjType);
17496            app.setAdj = app.curAdj;
17497        }
17498
17499        if (app.setSchedGroup != app.curSchedGroup) {
17500            app.setSchedGroup = app.curSchedGroup;
17501            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17502                    "Setting process group of " + app.processName
17503                    + " to " + app.curSchedGroup);
17504            if (app.waitingToKill != null &&
17505                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17506                app.kill(app.waitingToKill, true);
17507                success = false;
17508            } else {
17509                if (true) {
17510                    long oldId = Binder.clearCallingIdentity();
17511                    try {
17512                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17513                    } catch (Exception e) {
17514                        Slog.w(TAG, "Failed setting process group of " + app.pid
17515                                + " to " + app.curSchedGroup);
17516                        e.printStackTrace();
17517                    } finally {
17518                        Binder.restoreCallingIdentity(oldId);
17519                    }
17520                } else {
17521                    if (app.thread != null) {
17522                        try {
17523                            app.thread.setSchedulingGroup(app.curSchedGroup);
17524                        } catch (RemoteException e) {
17525                        }
17526                    }
17527                }
17528                Process.setSwappiness(app.pid,
17529                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17530            }
17531        }
17532        if (app.repForegroundActivities != app.foregroundActivities) {
17533            app.repForegroundActivities = app.foregroundActivities;
17534            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17535        }
17536        if (app.repProcState != app.curProcState) {
17537            app.repProcState = app.curProcState;
17538            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17539            if (app.thread != null) {
17540                try {
17541                    if (false) {
17542                        //RuntimeException h = new RuntimeException("here");
17543                        Slog.i(TAG, "Sending new process state " + app.repProcState
17544                                + " to " + app /*, h*/);
17545                    }
17546                    app.thread.setProcessState(app.repProcState);
17547                } catch (RemoteException e) {
17548                }
17549            }
17550        }
17551        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17552                app.setProcState)) {
17553            app.lastStateTime = now;
17554            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17555                    isSleeping(), now);
17556            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17557                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17558                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17559                    + (app.nextPssTime-now) + ": " + app);
17560        } else {
17561            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17562                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17563                requestPssLocked(app, app.setProcState);
17564                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17565                        isSleeping(), now);
17566            } else if (false && DEBUG_PSS) {
17567                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17568            }
17569        }
17570        if (app.setProcState != app.curProcState) {
17571            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17572                    "Proc state change of " + app.processName
17573                    + " to " + app.curProcState);
17574            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17575            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17576            if (setImportant && !curImportant) {
17577                // This app is no longer something we consider important enough to allow to
17578                // use arbitrary amounts of battery power.  Note
17579                // its current wake lock time to later know to kill it if
17580                // it is not behaving well.
17581                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17582                synchronized (stats) {
17583                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17584                            app.pid, SystemClock.elapsedRealtime());
17585                }
17586                app.lastCpuTime = app.curCpuTime;
17587
17588            }
17589            app.setProcState = app.curProcState;
17590            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17591                app.notCachedSinceIdle = false;
17592            }
17593            if (!doingAll) {
17594                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17595            } else {
17596                app.procStateChanged = true;
17597            }
17598        }
17599
17600        if (changes != 0) {
17601            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17602            int i = mPendingProcessChanges.size()-1;
17603            ProcessChangeItem item = null;
17604            while (i >= 0) {
17605                item = mPendingProcessChanges.get(i);
17606                if (item.pid == app.pid) {
17607                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17608                    break;
17609                }
17610                i--;
17611            }
17612            if (i < 0) {
17613                // No existing item in pending changes; need a new one.
17614                final int NA = mAvailProcessChanges.size();
17615                if (NA > 0) {
17616                    item = mAvailProcessChanges.remove(NA-1);
17617                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17618                } else {
17619                    item = new ProcessChangeItem();
17620                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17621                }
17622                item.changes = 0;
17623                item.pid = app.pid;
17624                item.uid = app.info.uid;
17625                if (mPendingProcessChanges.size() == 0) {
17626                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17627                            "*** Enqueueing dispatch processes changed!");
17628                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17629                }
17630                mPendingProcessChanges.add(item);
17631            }
17632            item.changes |= changes;
17633            item.processState = app.repProcState;
17634            item.foregroundActivities = app.repForegroundActivities;
17635            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17636                    + Integer.toHexString(System.identityHashCode(item))
17637                    + " " + app.toShortString() + ": changes=" + item.changes
17638                    + " procState=" + item.processState
17639                    + " foreground=" + item.foregroundActivities
17640                    + " type=" + app.adjType + " source=" + app.adjSource
17641                    + " target=" + app.adjTarget);
17642        }
17643
17644        return success;
17645    }
17646
17647    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17648        if (proc.thread != null) {
17649            if (proc.baseProcessTracker != null) {
17650                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17651            }
17652            if (proc.repProcState >= 0) {
17653                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17654                        proc.repProcState);
17655            }
17656        }
17657    }
17658
17659    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17660            ProcessRecord TOP_APP, boolean doingAll, long now) {
17661        if (app.thread == null) {
17662            return false;
17663        }
17664
17665        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17666
17667        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17668    }
17669
17670    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17671            boolean oomAdj) {
17672        if (isForeground != proc.foregroundServices) {
17673            proc.foregroundServices = isForeground;
17674            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17675                    proc.info.uid);
17676            if (isForeground) {
17677                if (curProcs == null) {
17678                    curProcs = new ArrayList<ProcessRecord>();
17679                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17680                }
17681                if (!curProcs.contains(proc)) {
17682                    curProcs.add(proc);
17683                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17684                            proc.info.packageName, proc.info.uid);
17685                }
17686            } else {
17687                if (curProcs != null) {
17688                    if (curProcs.remove(proc)) {
17689                        mBatteryStatsService.noteEvent(
17690                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17691                                proc.info.packageName, proc.info.uid);
17692                        if (curProcs.size() <= 0) {
17693                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17694                        }
17695                    }
17696                }
17697            }
17698            if (oomAdj) {
17699                updateOomAdjLocked();
17700            }
17701        }
17702    }
17703
17704    private final ActivityRecord resumedAppLocked() {
17705        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17706        String pkg;
17707        int uid;
17708        if (act != null) {
17709            pkg = act.packageName;
17710            uid = act.info.applicationInfo.uid;
17711        } else {
17712            pkg = null;
17713            uid = -1;
17714        }
17715        // Has the UID or resumed package name changed?
17716        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17717                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17718            if (mCurResumedPackage != null) {
17719                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17720                        mCurResumedPackage, mCurResumedUid);
17721            }
17722            mCurResumedPackage = pkg;
17723            mCurResumedUid = uid;
17724            if (mCurResumedPackage != null) {
17725                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17726                        mCurResumedPackage, mCurResumedUid);
17727            }
17728        }
17729        return act;
17730    }
17731
17732    final boolean updateOomAdjLocked(ProcessRecord app) {
17733        final ActivityRecord TOP_ACT = resumedAppLocked();
17734        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17735        final boolean wasCached = app.cached;
17736
17737        mAdjSeq++;
17738
17739        // This is the desired cached adjusment we want to tell it to use.
17740        // If our app is currently cached, we know it, and that is it.  Otherwise,
17741        // we don't know it yet, and it needs to now be cached we will then
17742        // need to do a complete oom adj.
17743        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17744                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17745        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17746                SystemClock.uptimeMillis());
17747        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17748            // Changed to/from cached state, so apps after it in the LRU
17749            // list may also be changed.
17750            updateOomAdjLocked();
17751        }
17752        return success;
17753    }
17754
17755    final void updateOomAdjLocked() {
17756        final ActivityRecord TOP_ACT = resumedAppLocked();
17757        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17758        final long now = SystemClock.uptimeMillis();
17759        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17760        final int N = mLruProcesses.size();
17761
17762        if (false) {
17763            RuntimeException e = new RuntimeException();
17764            e.fillInStackTrace();
17765            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17766        }
17767
17768        mAdjSeq++;
17769        mNewNumServiceProcs = 0;
17770        mNewNumAServiceProcs = 0;
17771
17772        final int emptyProcessLimit;
17773        final int cachedProcessLimit;
17774        if (mProcessLimit <= 0) {
17775            emptyProcessLimit = cachedProcessLimit = 0;
17776        } else if (mProcessLimit == 1) {
17777            emptyProcessLimit = 1;
17778            cachedProcessLimit = 0;
17779        } else {
17780            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17781            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17782        }
17783
17784        // Let's determine how many processes we have running vs.
17785        // how many slots we have for background processes; we may want
17786        // to put multiple processes in a slot of there are enough of
17787        // them.
17788        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17789                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17790        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17791        if (numEmptyProcs > cachedProcessLimit) {
17792            // If there are more empty processes than our limit on cached
17793            // processes, then use the cached process limit for the factor.
17794            // This ensures that the really old empty processes get pushed
17795            // down to the bottom, so if we are running low on memory we will
17796            // have a better chance at keeping around more cached processes
17797            // instead of a gazillion empty processes.
17798            numEmptyProcs = cachedProcessLimit;
17799        }
17800        int emptyFactor = numEmptyProcs/numSlots;
17801        if (emptyFactor < 1) emptyFactor = 1;
17802        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17803        if (cachedFactor < 1) cachedFactor = 1;
17804        int stepCached = 0;
17805        int stepEmpty = 0;
17806        int numCached = 0;
17807        int numEmpty = 0;
17808        int numTrimming = 0;
17809
17810        mNumNonCachedProcs = 0;
17811        mNumCachedHiddenProcs = 0;
17812
17813        // First update the OOM adjustment for each of the
17814        // application processes based on their current state.
17815        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17816        int nextCachedAdj = curCachedAdj+1;
17817        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17818        int nextEmptyAdj = curEmptyAdj+2;
17819        for (int i=N-1; i>=0; i--) {
17820            ProcessRecord app = mLruProcesses.get(i);
17821            if (!app.killedByAm && app.thread != null) {
17822                app.procStateChanged = false;
17823                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17824
17825                // If we haven't yet assigned the final cached adj
17826                // to the process, do that now.
17827                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17828                    switch (app.curProcState) {
17829                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17830                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17831                            // This process is a cached process holding activities...
17832                            // assign it the next cached value for that type, and then
17833                            // step that cached level.
17834                            app.curRawAdj = curCachedAdj;
17835                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17836                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17837                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17838                                    + ")");
17839                            if (curCachedAdj != nextCachedAdj) {
17840                                stepCached++;
17841                                if (stepCached >= cachedFactor) {
17842                                    stepCached = 0;
17843                                    curCachedAdj = nextCachedAdj;
17844                                    nextCachedAdj += 2;
17845                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17846                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17847                                    }
17848                                }
17849                            }
17850                            break;
17851                        default:
17852                            // For everything else, assign next empty cached process
17853                            // level and bump that up.  Note that this means that
17854                            // long-running services that have dropped down to the
17855                            // cached level will be treated as empty (since their process
17856                            // state is still as a service), which is what we want.
17857                            app.curRawAdj = curEmptyAdj;
17858                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17859                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17860                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17861                                    + ")");
17862                            if (curEmptyAdj != nextEmptyAdj) {
17863                                stepEmpty++;
17864                                if (stepEmpty >= emptyFactor) {
17865                                    stepEmpty = 0;
17866                                    curEmptyAdj = nextEmptyAdj;
17867                                    nextEmptyAdj += 2;
17868                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17869                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17870                                    }
17871                                }
17872                            }
17873                            break;
17874                    }
17875                }
17876
17877                applyOomAdjLocked(app, TOP_APP, true, now);
17878
17879                // Count the number of process types.
17880                switch (app.curProcState) {
17881                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17882                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17883                        mNumCachedHiddenProcs++;
17884                        numCached++;
17885                        if (numCached > cachedProcessLimit) {
17886                            app.kill("cached #" + numCached, true);
17887                        }
17888                        break;
17889                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17890                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17891                                && app.lastActivityTime < oldTime) {
17892                            app.kill("empty for "
17893                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17894                                    / 1000) + "s", true);
17895                        } else {
17896                            numEmpty++;
17897                            if (numEmpty > emptyProcessLimit) {
17898                                app.kill("empty #" + numEmpty, true);
17899                            }
17900                        }
17901                        break;
17902                    default:
17903                        mNumNonCachedProcs++;
17904                        break;
17905                }
17906
17907                if (app.isolated && app.services.size() <= 0) {
17908                    // If this is an isolated process, and there are no
17909                    // services running in it, then the process is no longer
17910                    // needed.  We agressively kill these because we can by
17911                    // definition not re-use the same process again, and it is
17912                    // good to avoid having whatever code was running in them
17913                    // left sitting around after no longer needed.
17914                    app.kill("isolated not needed", true);
17915                }
17916
17917                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17918                        && !app.killedByAm) {
17919                    numTrimming++;
17920                }
17921            }
17922        }
17923
17924        mNumServiceProcs = mNewNumServiceProcs;
17925
17926        // Now determine the memory trimming level of background processes.
17927        // Unfortunately we need to start at the back of the list to do this
17928        // properly.  We only do this if the number of background apps we
17929        // are managing to keep around is less than half the maximum we desire;
17930        // if we are keeping a good number around, we'll let them use whatever
17931        // memory they want.
17932        final int numCachedAndEmpty = numCached + numEmpty;
17933        int memFactor;
17934        if (numCached <= ProcessList.TRIM_CACHED_APPS
17935                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17936            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17937                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17938            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17939                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17940            } else {
17941                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17942            }
17943        } else {
17944            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17945        }
17946        // We always allow the memory level to go up (better).  We only allow it to go
17947        // down if we are in a state where that is allowed, *and* the total number of processes
17948        // has gone down since last time.
17949        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17950                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17951                + " last=" + mLastNumProcesses);
17952        if (memFactor > mLastMemoryLevel) {
17953            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17954                memFactor = mLastMemoryLevel;
17955                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17956            }
17957        }
17958        mLastMemoryLevel = memFactor;
17959        mLastNumProcesses = mLruProcesses.size();
17960        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17961        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17962        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17963            if (mLowRamStartTime == 0) {
17964                mLowRamStartTime = now;
17965            }
17966            int step = 0;
17967            int fgTrimLevel;
17968            switch (memFactor) {
17969                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17970                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17971                    break;
17972                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17973                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17974                    break;
17975                default:
17976                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17977                    break;
17978            }
17979            int factor = numTrimming/3;
17980            int minFactor = 2;
17981            if (mHomeProcess != null) minFactor++;
17982            if (mPreviousProcess != null) minFactor++;
17983            if (factor < minFactor) factor = minFactor;
17984            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17985            for (int i=N-1; i>=0; i--) {
17986                ProcessRecord app = mLruProcesses.get(i);
17987                if (allChanged || app.procStateChanged) {
17988                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17989                    app.procStateChanged = false;
17990                }
17991                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17992                        && !app.killedByAm) {
17993                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17994                        try {
17995                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17996                                    "Trimming memory of " + app.processName
17997                                    + " to " + curLevel);
17998                            app.thread.scheduleTrimMemory(curLevel);
17999                        } catch (RemoteException e) {
18000                        }
18001                        if (false) {
18002                            // For now we won't do this; our memory trimming seems
18003                            // to be good enough at this point that destroying
18004                            // activities causes more harm than good.
18005                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18006                                    && app != mHomeProcess && app != mPreviousProcess) {
18007                                // Need to do this on its own message because the stack may not
18008                                // be in a consistent state at this point.
18009                                // For these apps we will also finish their activities
18010                                // to help them free memory.
18011                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18012                            }
18013                        }
18014                    }
18015                    app.trimMemoryLevel = curLevel;
18016                    step++;
18017                    if (step >= factor) {
18018                        step = 0;
18019                        switch (curLevel) {
18020                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18021                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18022                                break;
18023                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18024                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18025                                break;
18026                        }
18027                    }
18028                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18029                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18030                            && app.thread != null) {
18031                        try {
18032                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18033                                    "Trimming memory of heavy-weight " + app.processName
18034                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18035                            app.thread.scheduleTrimMemory(
18036                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18037                        } catch (RemoteException e) {
18038                        }
18039                    }
18040                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18041                } else {
18042                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18043                            || app.systemNoUi) && app.pendingUiClean) {
18044                        // If this application is now in the background and it
18045                        // had done UI, then give it the special trim level to
18046                        // have it free UI resources.
18047                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18048                        if (app.trimMemoryLevel < level && app.thread != null) {
18049                            try {
18050                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18051                                        "Trimming memory of bg-ui " + app.processName
18052                                        + " to " + level);
18053                                app.thread.scheduleTrimMemory(level);
18054                            } catch (RemoteException e) {
18055                            }
18056                        }
18057                        app.pendingUiClean = false;
18058                    }
18059                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18060                        try {
18061                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18062                                    "Trimming memory of fg " + app.processName
18063                                    + " to " + fgTrimLevel);
18064                            app.thread.scheduleTrimMemory(fgTrimLevel);
18065                        } catch (RemoteException e) {
18066                        }
18067                    }
18068                    app.trimMemoryLevel = fgTrimLevel;
18069                }
18070            }
18071        } else {
18072            if (mLowRamStartTime != 0) {
18073                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18074                mLowRamStartTime = 0;
18075            }
18076            for (int i=N-1; i>=0; i--) {
18077                ProcessRecord app = mLruProcesses.get(i);
18078                if (allChanged || app.procStateChanged) {
18079                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18080                    app.procStateChanged = false;
18081                }
18082                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18083                        || app.systemNoUi) && app.pendingUiClean) {
18084                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18085                            && app.thread != null) {
18086                        try {
18087                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18088                                    "Trimming memory of ui hidden " + app.processName
18089                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18090                            app.thread.scheduleTrimMemory(
18091                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18092                        } catch (RemoteException e) {
18093                        }
18094                    }
18095                    app.pendingUiClean = false;
18096                }
18097                app.trimMemoryLevel = 0;
18098            }
18099        }
18100
18101        if (mAlwaysFinishActivities) {
18102            // Need to do this on its own message because the stack may not
18103            // be in a consistent state at this point.
18104            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18105        }
18106
18107        if (allChanged) {
18108            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18109        }
18110
18111        if (mProcessStats.shouldWriteNowLocked(now)) {
18112            mHandler.post(new Runnable() {
18113                @Override public void run() {
18114                    synchronized (ActivityManagerService.this) {
18115                        mProcessStats.writeStateAsyncLocked();
18116                    }
18117                }
18118            });
18119        }
18120
18121        if (DEBUG_OOM_ADJ) {
18122            if (false) {
18123                RuntimeException here = new RuntimeException("here");
18124                here.fillInStackTrace();
18125                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18126            } else {
18127                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18128            }
18129        }
18130    }
18131
18132    final void trimApplications() {
18133        synchronized (this) {
18134            int i;
18135
18136            // First remove any unused application processes whose package
18137            // has been removed.
18138            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18139                final ProcessRecord app = mRemovedProcesses.get(i);
18140                if (app.activities.size() == 0
18141                        && app.curReceiver == null && app.services.size() == 0) {
18142                    Slog.i(
18143                        TAG, "Exiting empty application process "
18144                        + app.processName + " ("
18145                        + (app.thread != null ? app.thread.asBinder() : null)
18146                        + ")\n");
18147                    if (app.pid > 0 && app.pid != MY_PID) {
18148                        app.kill("empty", false);
18149                    } else {
18150                        try {
18151                            app.thread.scheduleExit();
18152                        } catch (Exception e) {
18153                            // Ignore exceptions.
18154                        }
18155                    }
18156                    cleanUpApplicationRecordLocked(app, false, true, -1);
18157                    mRemovedProcesses.remove(i);
18158
18159                    if (app.persistent) {
18160                        addAppLocked(app.info, false, null /* ABI override */);
18161                    }
18162                }
18163            }
18164
18165            // Now update the oom adj for all processes.
18166            updateOomAdjLocked();
18167        }
18168    }
18169
18170    /** This method sends the specified signal to each of the persistent apps */
18171    public void signalPersistentProcesses(int sig) throws RemoteException {
18172        if (sig != Process.SIGNAL_USR1) {
18173            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18174        }
18175
18176        synchronized (this) {
18177            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18178                    != PackageManager.PERMISSION_GRANTED) {
18179                throw new SecurityException("Requires permission "
18180                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18181            }
18182
18183            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18184                ProcessRecord r = mLruProcesses.get(i);
18185                if (r.thread != null && r.persistent) {
18186                    Process.sendSignal(r.pid, sig);
18187                }
18188            }
18189        }
18190    }
18191
18192    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18193        if (proc == null || proc == mProfileProc) {
18194            proc = mProfileProc;
18195            profileType = mProfileType;
18196            clearProfilerLocked();
18197        }
18198        if (proc == null) {
18199            return;
18200        }
18201        try {
18202            proc.thread.profilerControl(false, null, profileType);
18203        } catch (RemoteException e) {
18204            throw new IllegalStateException("Process disappeared");
18205        }
18206    }
18207
18208    private void clearProfilerLocked() {
18209        if (mProfileFd != null) {
18210            try {
18211                mProfileFd.close();
18212            } catch (IOException e) {
18213            }
18214        }
18215        mProfileApp = null;
18216        mProfileProc = null;
18217        mProfileFile = null;
18218        mProfileType = 0;
18219        mAutoStopProfiler = false;
18220        mSamplingInterval = 0;
18221    }
18222
18223    public boolean profileControl(String process, int userId, boolean start,
18224            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18225
18226        try {
18227            synchronized (this) {
18228                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18229                // its own permission.
18230                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18231                        != PackageManager.PERMISSION_GRANTED) {
18232                    throw new SecurityException("Requires permission "
18233                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18234                }
18235
18236                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18237                    throw new IllegalArgumentException("null profile info or fd");
18238                }
18239
18240                ProcessRecord proc = null;
18241                if (process != null) {
18242                    proc = findProcessLocked(process, userId, "profileControl");
18243                }
18244
18245                if (start && (proc == null || proc.thread == null)) {
18246                    throw new IllegalArgumentException("Unknown process: " + process);
18247                }
18248
18249                if (start) {
18250                    stopProfilerLocked(null, 0);
18251                    setProfileApp(proc.info, proc.processName, profilerInfo);
18252                    mProfileProc = proc;
18253                    mProfileType = profileType;
18254                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18255                    try {
18256                        fd = fd.dup();
18257                    } catch (IOException e) {
18258                        fd = null;
18259                    }
18260                    profilerInfo.profileFd = fd;
18261                    proc.thread.profilerControl(start, profilerInfo, profileType);
18262                    fd = null;
18263                    mProfileFd = null;
18264                } else {
18265                    stopProfilerLocked(proc, profileType);
18266                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18267                        try {
18268                            profilerInfo.profileFd.close();
18269                        } catch (IOException e) {
18270                        }
18271                    }
18272                }
18273
18274                return true;
18275            }
18276        } catch (RemoteException e) {
18277            throw new IllegalStateException("Process disappeared");
18278        } finally {
18279            if (profilerInfo != null && profilerInfo.profileFd != null) {
18280                try {
18281                    profilerInfo.profileFd.close();
18282                } catch (IOException e) {
18283                }
18284            }
18285        }
18286    }
18287
18288    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18289        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18290                userId, true, ALLOW_FULL_ONLY, callName, null);
18291        ProcessRecord proc = null;
18292        try {
18293            int pid = Integer.parseInt(process);
18294            synchronized (mPidsSelfLocked) {
18295                proc = mPidsSelfLocked.get(pid);
18296            }
18297        } catch (NumberFormatException e) {
18298        }
18299
18300        if (proc == null) {
18301            ArrayMap<String, SparseArray<ProcessRecord>> all
18302                    = mProcessNames.getMap();
18303            SparseArray<ProcessRecord> procs = all.get(process);
18304            if (procs != null && procs.size() > 0) {
18305                proc = procs.valueAt(0);
18306                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18307                    for (int i=1; i<procs.size(); i++) {
18308                        ProcessRecord thisProc = procs.valueAt(i);
18309                        if (thisProc.userId == userId) {
18310                            proc = thisProc;
18311                            break;
18312                        }
18313                    }
18314                }
18315            }
18316        }
18317
18318        return proc;
18319    }
18320
18321    public boolean dumpHeap(String process, int userId, boolean managed,
18322            String path, ParcelFileDescriptor fd) throws RemoteException {
18323
18324        try {
18325            synchronized (this) {
18326                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18327                // its own permission (same as profileControl).
18328                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18329                        != PackageManager.PERMISSION_GRANTED) {
18330                    throw new SecurityException("Requires permission "
18331                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18332                }
18333
18334                if (fd == null) {
18335                    throw new IllegalArgumentException("null fd");
18336                }
18337
18338                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18339                if (proc == null || proc.thread == null) {
18340                    throw new IllegalArgumentException("Unknown process: " + process);
18341                }
18342
18343                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18344                if (!isDebuggable) {
18345                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18346                        throw new SecurityException("Process not debuggable: " + proc);
18347                    }
18348                }
18349
18350                proc.thread.dumpHeap(managed, path, fd);
18351                fd = null;
18352                return true;
18353            }
18354        } catch (RemoteException e) {
18355            throw new IllegalStateException("Process disappeared");
18356        } finally {
18357            if (fd != null) {
18358                try {
18359                    fd.close();
18360                } catch (IOException e) {
18361                }
18362            }
18363        }
18364    }
18365
18366    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18367    public void monitor() {
18368        synchronized (this) { }
18369    }
18370
18371    void onCoreSettingsChange(Bundle settings) {
18372        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18373            ProcessRecord processRecord = mLruProcesses.get(i);
18374            try {
18375                if (processRecord.thread != null) {
18376                    processRecord.thread.setCoreSettings(settings);
18377                }
18378            } catch (RemoteException re) {
18379                /* ignore */
18380            }
18381        }
18382    }
18383
18384    // Multi-user methods
18385
18386    /**
18387     * Start user, if its not already running, but don't bring it to foreground.
18388     */
18389    @Override
18390    public boolean startUserInBackground(final int userId) {
18391        return startUser(userId, /* foreground */ false);
18392    }
18393
18394    /**
18395     * Start user, if its not already running, and bring it to foreground.
18396     */
18397    boolean startUserInForeground(final int userId, Dialog dlg) {
18398        boolean result = startUser(userId, /* foreground */ true);
18399        dlg.dismiss();
18400        return result;
18401    }
18402
18403    /**
18404     * Refreshes the list of users related to the current user when either a
18405     * user switch happens or when a new related user is started in the
18406     * background.
18407     */
18408    private void updateCurrentProfileIdsLocked() {
18409        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18410                mCurrentUserId, false /* enabledOnly */);
18411        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18412        for (int i = 0; i < currentProfileIds.length; i++) {
18413            currentProfileIds[i] = profiles.get(i).id;
18414        }
18415        mCurrentProfileIds = currentProfileIds;
18416
18417        synchronized (mUserProfileGroupIdsSelfLocked) {
18418            mUserProfileGroupIdsSelfLocked.clear();
18419            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18420            for (int i = 0; i < users.size(); i++) {
18421                UserInfo user = users.get(i);
18422                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18423                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18424                }
18425            }
18426        }
18427    }
18428
18429    private Set getProfileIdsLocked(int userId) {
18430        Set userIds = new HashSet<Integer>();
18431        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18432                userId, false /* enabledOnly */);
18433        for (UserInfo user : profiles) {
18434            userIds.add(Integer.valueOf(user.id));
18435        }
18436        return userIds;
18437    }
18438
18439    @Override
18440    public boolean switchUser(final int userId) {
18441        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18442        String userName;
18443        synchronized (this) {
18444            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18445            if (userInfo == null) {
18446                Slog.w(TAG, "No user info for user #" + userId);
18447                return false;
18448            }
18449            if (userInfo.isManagedProfile()) {
18450                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18451                return false;
18452            }
18453            userName = userInfo.name;
18454            mTargetUserId = userId;
18455        }
18456        mHandler.removeMessages(START_USER_SWITCH_MSG);
18457        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18458        return true;
18459    }
18460
18461    private void showUserSwitchDialog(int userId, String userName) {
18462        // The dialog will show and then initiate the user switch by calling startUserInForeground
18463        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18464                true /* above system */);
18465        d.show();
18466    }
18467
18468    private boolean startUser(final int userId, final boolean foreground) {
18469        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18470                != PackageManager.PERMISSION_GRANTED) {
18471            String msg = "Permission Denial: switchUser() from pid="
18472                    + Binder.getCallingPid()
18473                    + ", uid=" + Binder.getCallingUid()
18474                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18475            Slog.w(TAG, msg);
18476            throw new SecurityException(msg);
18477        }
18478
18479        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18480
18481        final long ident = Binder.clearCallingIdentity();
18482        try {
18483            synchronized (this) {
18484                final int oldUserId = mCurrentUserId;
18485                if (oldUserId == userId) {
18486                    return true;
18487                }
18488
18489                mStackSupervisor.setLockTaskModeLocked(null, false);
18490
18491                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18492                if (userInfo == null) {
18493                    Slog.w(TAG, "No user info for user #" + userId);
18494                    return false;
18495                }
18496                if (foreground && userInfo.isManagedProfile()) {
18497                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18498                    return false;
18499                }
18500
18501                if (foreground) {
18502                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18503                            R.anim.screen_user_enter);
18504                }
18505
18506                boolean needStart = false;
18507
18508                // If the user we are switching to is not currently started, then
18509                // we need to start it now.
18510                if (mStartedUsers.get(userId) == null) {
18511                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18512                    updateStartedUserArrayLocked();
18513                    needStart = true;
18514                }
18515
18516                final Integer userIdInt = Integer.valueOf(userId);
18517                mUserLru.remove(userIdInt);
18518                mUserLru.add(userIdInt);
18519
18520                if (foreground) {
18521                    mCurrentUserId = userId;
18522                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18523                    updateCurrentProfileIdsLocked();
18524                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18525                    // Once the internal notion of the active user has switched, we lock the device
18526                    // with the option to show the user switcher on the keyguard.
18527                    mWindowManager.lockNow(null);
18528                } else {
18529                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18530                    updateCurrentProfileIdsLocked();
18531                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18532                    mUserLru.remove(currentUserIdInt);
18533                    mUserLru.add(currentUserIdInt);
18534                }
18535
18536                final UserStartedState uss = mStartedUsers.get(userId);
18537
18538                // Make sure user is in the started state.  If it is currently
18539                // stopping, we need to knock that off.
18540                if (uss.mState == UserStartedState.STATE_STOPPING) {
18541                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18542                    // so we can just fairly silently bring the user back from
18543                    // the almost-dead.
18544                    uss.mState = UserStartedState.STATE_RUNNING;
18545                    updateStartedUserArrayLocked();
18546                    needStart = true;
18547                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18548                    // This means ACTION_SHUTDOWN has been sent, so we will
18549                    // need to treat this as a new boot of the user.
18550                    uss.mState = UserStartedState.STATE_BOOTING;
18551                    updateStartedUserArrayLocked();
18552                    needStart = true;
18553                }
18554
18555                if (uss.mState == UserStartedState.STATE_BOOTING) {
18556                    // Booting up a new user, need to tell system services about it.
18557                    // Note that this is on the same handler as scheduling of broadcasts,
18558                    // which is important because it needs to go first.
18559                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18560                }
18561
18562                if (foreground) {
18563                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18564                            oldUserId));
18565                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18566                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18567                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18568                            oldUserId, userId, uss));
18569                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18570                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18571                }
18572
18573                if (needStart) {
18574                    // Send USER_STARTED broadcast
18575                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18576                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18577                            | Intent.FLAG_RECEIVER_FOREGROUND);
18578                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18579                    broadcastIntentLocked(null, null, intent,
18580                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18581                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18582                }
18583
18584                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18585                    if (userId != UserHandle.USER_OWNER) {
18586                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18587                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18588                        broadcastIntentLocked(null, null, intent, null,
18589                                new IIntentReceiver.Stub() {
18590                                    public void performReceive(Intent intent, int resultCode,
18591                                            String data, Bundle extras, boolean ordered,
18592                                            boolean sticky, int sendingUser) {
18593                                        onUserInitialized(uss, foreground, oldUserId, userId);
18594                                    }
18595                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18596                                true, false, MY_PID, Process.SYSTEM_UID,
18597                                userId);
18598                        uss.initializing = true;
18599                    } else {
18600                        getUserManagerLocked().makeInitialized(userInfo.id);
18601                    }
18602                }
18603
18604                if (foreground) {
18605                    if (!uss.initializing) {
18606                        moveUserToForeground(uss, oldUserId, userId);
18607                    }
18608                } else {
18609                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18610                }
18611
18612                if (needStart) {
18613                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18614                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18615                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18616                    broadcastIntentLocked(null, null, intent,
18617                            null, new IIntentReceiver.Stub() {
18618                                @Override
18619                                public void performReceive(Intent intent, int resultCode, String data,
18620                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18621                                        throws RemoteException {
18622                                }
18623                            }, 0, null, null,
18624                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18625                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18626                }
18627            }
18628        } finally {
18629            Binder.restoreCallingIdentity(ident);
18630        }
18631
18632        return true;
18633    }
18634
18635    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18636        long ident = Binder.clearCallingIdentity();
18637        try {
18638            Intent intent;
18639            if (oldUserId >= 0) {
18640                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18641                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18642                int count = profiles.size();
18643                for (int i = 0; i < count; i++) {
18644                    int profileUserId = profiles.get(i).id;
18645                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18646                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18647                            | Intent.FLAG_RECEIVER_FOREGROUND);
18648                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18649                    broadcastIntentLocked(null, null, intent,
18650                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18651                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18652                }
18653            }
18654            if (newUserId >= 0) {
18655                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18656                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18657                int count = profiles.size();
18658                for (int i = 0; i < count; i++) {
18659                    int profileUserId = profiles.get(i).id;
18660                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18661                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18662                            | Intent.FLAG_RECEIVER_FOREGROUND);
18663                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18664                    broadcastIntentLocked(null, null, intent,
18665                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18666                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18667                }
18668                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18669                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18670                        | Intent.FLAG_RECEIVER_FOREGROUND);
18671                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18672                broadcastIntentLocked(null, null, intent,
18673                        null, null, 0, null, null,
18674                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18675                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18676            }
18677        } finally {
18678            Binder.restoreCallingIdentity(ident);
18679        }
18680    }
18681
18682    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18683            final int newUserId) {
18684        final int N = mUserSwitchObservers.beginBroadcast();
18685        if (N > 0) {
18686            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18687                int mCount = 0;
18688                @Override
18689                public void sendResult(Bundle data) throws RemoteException {
18690                    synchronized (ActivityManagerService.this) {
18691                        if (mCurUserSwitchCallback == this) {
18692                            mCount++;
18693                            if (mCount == N) {
18694                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18695                            }
18696                        }
18697                    }
18698                }
18699            };
18700            synchronized (this) {
18701                uss.switching = true;
18702                mCurUserSwitchCallback = callback;
18703            }
18704            for (int i=0; i<N; i++) {
18705                try {
18706                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18707                            newUserId, callback);
18708                } catch (RemoteException e) {
18709                }
18710            }
18711        } else {
18712            synchronized (this) {
18713                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18714            }
18715        }
18716        mUserSwitchObservers.finishBroadcast();
18717    }
18718
18719    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18720        synchronized (this) {
18721            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18722            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18723        }
18724    }
18725
18726    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18727        mCurUserSwitchCallback = null;
18728        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18729        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18730                oldUserId, newUserId, uss));
18731    }
18732
18733    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18734        synchronized (this) {
18735            if (foreground) {
18736                moveUserToForeground(uss, oldUserId, newUserId);
18737            }
18738        }
18739
18740        completeSwitchAndInitalize(uss, newUserId, true, false);
18741    }
18742
18743    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18744        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18745        if (homeInFront) {
18746            startHomeActivityLocked(newUserId);
18747        } else {
18748            mStackSupervisor.resumeTopActivitiesLocked();
18749        }
18750        EventLogTags.writeAmSwitchUser(newUserId);
18751        getUserManagerLocked().userForeground(newUserId);
18752        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18753    }
18754
18755    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18756        completeSwitchAndInitalize(uss, newUserId, false, true);
18757    }
18758
18759    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18760            boolean clearInitializing, boolean clearSwitching) {
18761        boolean unfrozen = false;
18762        synchronized (this) {
18763            if (clearInitializing) {
18764                uss.initializing = false;
18765                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18766            }
18767            if (clearSwitching) {
18768                uss.switching = false;
18769            }
18770            if (!uss.switching && !uss.initializing) {
18771                mWindowManager.stopFreezingScreen();
18772                unfrozen = true;
18773            }
18774        }
18775        if (unfrozen) {
18776            final int N = mUserSwitchObservers.beginBroadcast();
18777            for (int i=0; i<N; i++) {
18778                try {
18779                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18780                } catch (RemoteException e) {
18781                }
18782            }
18783            mUserSwitchObservers.finishBroadcast();
18784        }
18785    }
18786
18787    void scheduleStartProfilesLocked() {
18788        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18789            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18790                    DateUtils.SECOND_IN_MILLIS);
18791        }
18792    }
18793
18794    void startProfilesLocked() {
18795        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18796        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18797                mCurrentUserId, false /* enabledOnly */);
18798        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18799        for (UserInfo user : profiles) {
18800            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18801                    && user.id != mCurrentUserId) {
18802                toStart.add(user);
18803            }
18804        }
18805        final int n = toStart.size();
18806        int i = 0;
18807        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18808            startUserInBackground(toStart.get(i).id);
18809        }
18810        if (i < n) {
18811            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18812        }
18813    }
18814
18815    void finishUserBoot(UserStartedState uss) {
18816        synchronized (this) {
18817            if (uss.mState == UserStartedState.STATE_BOOTING
18818                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18819                uss.mState = UserStartedState.STATE_RUNNING;
18820                final int userId = uss.mHandle.getIdentifier();
18821                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18822                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18823                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18824                broadcastIntentLocked(null, null, intent,
18825                        null, null, 0, null, null,
18826                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18827                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18828            }
18829        }
18830    }
18831
18832    void finishUserSwitch(UserStartedState uss) {
18833        synchronized (this) {
18834            finishUserBoot(uss);
18835
18836            startProfilesLocked();
18837
18838            int num = mUserLru.size();
18839            int i = 0;
18840            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18841                Integer oldUserId = mUserLru.get(i);
18842                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18843                if (oldUss == null) {
18844                    // Shouldn't happen, but be sane if it does.
18845                    mUserLru.remove(i);
18846                    num--;
18847                    continue;
18848                }
18849                if (oldUss.mState == UserStartedState.STATE_STOPPING
18850                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18851                    // This user is already stopping, doesn't count.
18852                    num--;
18853                    i++;
18854                    continue;
18855                }
18856                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18857                    // Owner and current can't be stopped, but count as running.
18858                    i++;
18859                    continue;
18860                }
18861                // This is a user to be stopped.
18862                stopUserLocked(oldUserId, null);
18863                num--;
18864                i++;
18865            }
18866        }
18867    }
18868
18869    @Override
18870    public int stopUser(final int userId, final IStopUserCallback callback) {
18871        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18872                != PackageManager.PERMISSION_GRANTED) {
18873            String msg = "Permission Denial: switchUser() from pid="
18874                    + Binder.getCallingPid()
18875                    + ", uid=" + Binder.getCallingUid()
18876                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18877            Slog.w(TAG, msg);
18878            throw new SecurityException(msg);
18879        }
18880        if (userId <= 0) {
18881            throw new IllegalArgumentException("Can't stop primary user " + userId);
18882        }
18883        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18884        synchronized (this) {
18885            return stopUserLocked(userId, callback);
18886        }
18887    }
18888
18889    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18890        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18891        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18892            return ActivityManager.USER_OP_IS_CURRENT;
18893        }
18894
18895        final UserStartedState uss = mStartedUsers.get(userId);
18896        if (uss == null) {
18897            // User is not started, nothing to do...  but we do need to
18898            // callback if requested.
18899            if (callback != null) {
18900                mHandler.post(new Runnable() {
18901                    @Override
18902                    public void run() {
18903                        try {
18904                            callback.userStopped(userId);
18905                        } catch (RemoteException e) {
18906                        }
18907                    }
18908                });
18909            }
18910            return ActivityManager.USER_OP_SUCCESS;
18911        }
18912
18913        if (callback != null) {
18914            uss.mStopCallbacks.add(callback);
18915        }
18916
18917        if (uss.mState != UserStartedState.STATE_STOPPING
18918                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18919            uss.mState = UserStartedState.STATE_STOPPING;
18920            updateStartedUserArrayLocked();
18921
18922            long ident = Binder.clearCallingIdentity();
18923            try {
18924                // We are going to broadcast ACTION_USER_STOPPING and then
18925                // once that is done send a final ACTION_SHUTDOWN and then
18926                // stop the user.
18927                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18928                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18929                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18930                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18931                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18932                // This is the result receiver for the final shutdown broadcast.
18933                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18934                    @Override
18935                    public void performReceive(Intent intent, int resultCode, String data,
18936                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18937                        finishUserStop(uss);
18938                    }
18939                };
18940                // This is the result receiver for the initial stopping broadcast.
18941                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18942                    @Override
18943                    public void performReceive(Intent intent, int resultCode, String data,
18944                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18945                        // On to the next.
18946                        synchronized (ActivityManagerService.this) {
18947                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18948                                // Whoops, we are being started back up.  Abort, abort!
18949                                return;
18950                            }
18951                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18952                        }
18953                        mBatteryStatsService.noteEvent(
18954                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18955                                Integer.toString(userId), userId);
18956                        mSystemServiceManager.stopUser(userId);
18957                        broadcastIntentLocked(null, null, shutdownIntent,
18958                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18959                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18960                    }
18961                };
18962                // Kick things off.
18963                broadcastIntentLocked(null, null, stoppingIntent,
18964                        null, stoppingReceiver, 0, null, null,
18965                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18966                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18967            } finally {
18968                Binder.restoreCallingIdentity(ident);
18969            }
18970        }
18971
18972        return ActivityManager.USER_OP_SUCCESS;
18973    }
18974
18975    void finishUserStop(UserStartedState uss) {
18976        final int userId = uss.mHandle.getIdentifier();
18977        boolean stopped;
18978        ArrayList<IStopUserCallback> callbacks;
18979        synchronized (this) {
18980            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18981            if (mStartedUsers.get(userId) != uss) {
18982                stopped = false;
18983            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18984                stopped = false;
18985            } else {
18986                stopped = true;
18987                // User can no longer run.
18988                mStartedUsers.remove(userId);
18989                mUserLru.remove(Integer.valueOf(userId));
18990                updateStartedUserArrayLocked();
18991
18992                // Clean up all state and processes associated with the user.
18993                // Kill all the processes for the user.
18994                forceStopUserLocked(userId, "finish user");
18995            }
18996
18997            // Explicitly remove the old information in mRecentTasks.
18998            removeRecentTasksForUserLocked(userId);
18999        }
19000
19001        for (int i=0; i<callbacks.size(); i++) {
19002            try {
19003                if (stopped) callbacks.get(i).userStopped(userId);
19004                else callbacks.get(i).userStopAborted(userId);
19005            } catch (RemoteException e) {
19006            }
19007        }
19008
19009        if (stopped) {
19010            mSystemServiceManager.cleanupUser(userId);
19011            synchronized (this) {
19012                mStackSupervisor.removeUserLocked(userId);
19013            }
19014        }
19015    }
19016
19017    @Override
19018    public UserInfo getCurrentUser() {
19019        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19020                != PackageManager.PERMISSION_GRANTED) && (
19021                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19022                != PackageManager.PERMISSION_GRANTED)) {
19023            String msg = "Permission Denial: getCurrentUser() from pid="
19024                    + Binder.getCallingPid()
19025                    + ", uid=" + Binder.getCallingUid()
19026                    + " requires " + INTERACT_ACROSS_USERS;
19027            Slog.w(TAG, msg);
19028            throw new SecurityException(msg);
19029        }
19030        synchronized (this) {
19031            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19032            return getUserManagerLocked().getUserInfo(userId);
19033        }
19034    }
19035
19036    int getCurrentUserIdLocked() {
19037        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19038    }
19039
19040    @Override
19041    public boolean isUserRunning(int userId, boolean orStopped) {
19042        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19043                != PackageManager.PERMISSION_GRANTED) {
19044            String msg = "Permission Denial: isUserRunning() from pid="
19045                    + Binder.getCallingPid()
19046                    + ", uid=" + Binder.getCallingUid()
19047                    + " requires " + INTERACT_ACROSS_USERS;
19048            Slog.w(TAG, msg);
19049            throw new SecurityException(msg);
19050        }
19051        synchronized (this) {
19052            return isUserRunningLocked(userId, orStopped);
19053        }
19054    }
19055
19056    boolean isUserRunningLocked(int userId, boolean orStopped) {
19057        UserStartedState state = mStartedUsers.get(userId);
19058        if (state == null) {
19059            return false;
19060        }
19061        if (orStopped) {
19062            return true;
19063        }
19064        return state.mState != UserStartedState.STATE_STOPPING
19065                && state.mState != UserStartedState.STATE_SHUTDOWN;
19066    }
19067
19068    @Override
19069    public int[] getRunningUserIds() {
19070        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19071                != PackageManager.PERMISSION_GRANTED) {
19072            String msg = "Permission Denial: isUserRunning() from pid="
19073                    + Binder.getCallingPid()
19074                    + ", uid=" + Binder.getCallingUid()
19075                    + " requires " + INTERACT_ACROSS_USERS;
19076            Slog.w(TAG, msg);
19077            throw new SecurityException(msg);
19078        }
19079        synchronized (this) {
19080            return mStartedUserArray;
19081        }
19082    }
19083
19084    private void updateStartedUserArrayLocked() {
19085        int num = 0;
19086        for (int i=0; i<mStartedUsers.size();  i++) {
19087            UserStartedState uss = mStartedUsers.valueAt(i);
19088            // This list does not include stopping users.
19089            if (uss.mState != UserStartedState.STATE_STOPPING
19090                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19091                num++;
19092            }
19093        }
19094        mStartedUserArray = new int[num];
19095        num = 0;
19096        for (int i=0; i<mStartedUsers.size();  i++) {
19097            UserStartedState uss = mStartedUsers.valueAt(i);
19098            if (uss.mState != UserStartedState.STATE_STOPPING
19099                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19100                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19101                num++;
19102            }
19103        }
19104    }
19105
19106    @Override
19107    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19108        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19109                != PackageManager.PERMISSION_GRANTED) {
19110            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19111                    + Binder.getCallingPid()
19112                    + ", uid=" + Binder.getCallingUid()
19113                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19114            Slog.w(TAG, msg);
19115            throw new SecurityException(msg);
19116        }
19117
19118        mUserSwitchObservers.register(observer);
19119    }
19120
19121    @Override
19122    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19123        mUserSwitchObservers.unregister(observer);
19124    }
19125
19126    private boolean userExists(int userId) {
19127        if (userId == 0) {
19128            return true;
19129        }
19130        UserManagerService ums = getUserManagerLocked();
19131        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19132    }
19133
19134    int[] getUsersLocked() {
19135        UserManagerService ums = getUserManagerLocked();
19136        return ums != null ? ums.getUserIds() : new int[] { 0 };
19137    }
19138
19139    UserManagerService getUserManagerLocked() {
19140        if (mUserManager == null) {
19141            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19142            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19143        }
19144        return mUserManager;
19145    }
19146
19147    private int applyUserId(int uid, int userId) {
19148        return UserHandle.getUid(userId, uid);
19149    }
19150
19151    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19152        if (info == null) return null;
19153        ApplicationInfo newInfo = new ApplicationInfo(info);
19154        newInfo.uid = applyUserId(info.uid, userId);
19155        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19156                + info.packageName;
19157        return newInfo;
19158    }
19159
19160    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19161        if (aInfo == null
19162                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19163            return aInfo;
19164        }
19165
19166        ActivityInfo info = new ActivityInfo(aInfo);
19167        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19168        return info;
19169    }
19170
19171    private final class LocalService extends ActivityManagerInternal {
19172        @Override
19173        public void goingToSleep() {
19174            ActivityManagerService.this.goingToSleep();
19175        }
19176
19177        @Override
19178        public void wakingUp() {
19179            ActivityManagerService.this.wakingUp();
19180        }
19181
19182        @Override
19183        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19184                String processName, String abiOverride, int uid, Runnable crashHandler) {
19185            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19186                    processName, abiOverride, uid, crashHandler);
19187        }
19188    }
19189
19190    /**
19191     * An implementation of IAppTask, that allows an app to manage its own tasks via
19192     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19193     * only the process that calls getAppTasks() can call the AppTask methods.
19194     */
19195    class AppTaskImpl extends IAppTask.Stub {
19196        private int mTaskId;
19197        private int mCallingUid;
19198
19199        public AppTaskImpl(int taskId, int callingUid) {
19200            mTaskId = taskId;
19201            mCallingUid = callingUid;
19202        }
19203
19204        private void checkCaller() {
19205            if (mCallingUid != Binder.getCallingUid()) {
19206                throw new SecurityException("Caller " + mCallingUid
19207                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19208            }
19209        }
19210
19211        @Override
19212        public void finishAndRemoveTask() {
19213            checkCaller();
19214
19215            synchronized (ActivityManagerService.this) {
19216                long origId = Binder.clearCallingIdentity();
19217                try {
19218                    if (!removeTaskByIdLocked(mTaskId, false)) {
19219                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19220                    }
19221                } finally {
19222                    Binder.restoreCallingIdentity(origId);
19223                }
19224            }
19225        }
19226
19227        @Override
19228        public ActivityManager.RecentTaskInfo getTaskInfo() {
19229            checkCaller();
19230
19231            synchronized (ActivityManagerService.this) {
19232                long origId = Binder.clearCallingIdentity();
19233                try {
19234                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19235                    if (tr == null) {
19236                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19237                    }
19238                    return createRecentTaskInfoFromTaskRecord(tr);
19239                } finally {
19240                    Binder.restoreCallingIdentity(origId);
19241                }
19242            }
19243        }
19244
19245        @Override
19246        public void moveToFront() {
19247            checkCaller();
19248
19249            final TaskRecord tr;
19250            synchronized (ActivityManagerService.this) {
19251                tr = recentTaskForIdLocked(mTaskId);
19252                if (tr == null) {
19253                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19254                }
19255                if (tr.getRootActivity() != null) {
19256                    moveTaskToFrontLocked(tr.taskId, 0, null);
19257                    return;
19258                }
19259            }
19260
19261            startActivityFromRecentsInner(tr.taskId, null);
19262        }
19263
19264        @Override
19265        public int startActivity(IBinder whoThread, String callingPackage,
19266                Intent intent, String resolvedType, Bundle options) {
19267            checkCaller();
19268
19269            int callingUser = UserHandle.getCallingUserId();
19270            TaskRecord tr;
19271            IApplicationThread appThread;
19272            synchronized (ActivityManagerService.this) {
19273                tr = recentTaskForIdLocked(mTaskId);
19274                if (tr == null) {
19275                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19276                }
19277                appThread = ApplicationThreadNative.asInterface(whoThread);
19278                if (appThread == null) {
19279                    throw new IllegalArgumentException("Bad app thread " + appThread);
19280                }
19281            }
19282            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19283                    resolvedType, null, null, null, null, 0, 0, null, null,
19284                    null, options, callingUser, null, tr);
19285        }
19286
19287        @Override
19288        public void setExcludeFromRecents(boolean exclude) {
19289            checkCaller();
19290
19291            synchronized (ActivityManagerService.this) {
19292                long origId = Binder.clearCallingIdentity();
19293                try {
19294                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19295                    if (tr == null) {
19296                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19297                    }
19298                    Intent intent = tr.getBaseIntent();
19299                    if (exclude) {
19300                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19301                    } else {
19302                        intent.setFlags(intent.getFlags()
19303                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19304                    }
19305                } finally {
19306                    Binder.restoreCallingIdentity(origId);
19307                }
19308            }
19309        }
19310    }
19311}
19312