ActivityManagerService.java revision 2faf91fbb300882afd1092b788aa16295eb3dde8
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.ITaskStackListener;
41import android.app.ProfilerInfo;
42import android.app.admin.DevicePolicyManager;
43import android.app.usage.UsageEvents;
44import android.app.usage.UsageStatsManagerInternal;
45import android.appwidget.AppWidgetManager;
46import android.content.res.Resources;
47import android.graphics.Bitmap;
48import android.graphics.Point;
49import android.graphics.Rect;
50import android.os.BatteryStats;
51import android.os.PersistableBundle;
52import android.os.storage.IMountService;
53import android.os.storage.StorageManager;
54import android.service.voice.IVoiceInteractionSession;
55import android.util.ArrayMap;
56import android.util.ArraySet;
57import android.util.SparseIntArray;
58
59import com.android.internal.R;
60import com.android.internal.annotations.GuardedBy;
61import com.android.internal.app.IAppOpsService;
62import com.android.internal.app.IVoiceInteractor;
63import com.android.internal.app.ProcessMap;
64import com.android.internal.app.ProcessStats;
65import com.android.internal.os.BackgroundThread;
66import com.android.internal.os.BatteryStatsImpl;
67import com.android.internal.os.ProcessCpuTracker;
68import com.android.internal.os.TransferPipe;
69import com.android.internal.os.Zygote;
70import com.android.internal.util.FastPrintWriter;
71import com.android.internal.util.FastXmlSerializer;
72import com.android.internal.util.MemInfoReader;
73import com.android.internal.util.Preconditions;
74import com.android.server.AppOpsService;
75import com.android.server.AttributeCache;
76import com.android.server.IntentResolver;
77import com.android.server.LocalServices;
78import com.android.server.ServiceThread;
79import com.android.server.SystemService;
80import com.android.server.SystemServiceManager;
81import com.android.server.Watchdog;
82import com.android.server.am.ActivityStack.ActivityState;
83import com.android.server.firewall.IntentFirewall;
84import com.android.server.pm.Installer;
85import com.android.server.pm.UserManagerService;
86import com.android.server.statusbar.StatusBarManagerInternal;
87import com.android.server.wm.AppTransition;
88import com.android.server.wm.WindowManagerService;
89import com.google.android.collect.Lists;
90import com.google.android.collect.Maps;
91
92import libcore.io.IoUtils;
93
94import org.xmlpull.v1.XmlPullParser;
95import org.xmlpull.v1.XmlPullParserException;
96import org.xmlpull.v1.XmlSerializer;
97
98import android.app.Activity;
99import android.app.ActivityManager;
100import android.app.ActivityManager.RunningTaskInfo;
101import android.app.ActivityManager.StackInfo;
102import android.app.ActivityManagerInternal;
103import android.app.ActivityManagerNative;
104import android.app.ActivityOptions;
105import android.app.ActivityThread;
106import android.app.AlertDialog;
107import android.app.AppGlobals;
108import android.app.ApplicationErrorReport;
109import android.app.Dialog;
110import android.app.IActivityController;
111import android.app.IApplicationThread;
112import android.app.IInstrumentationWatcher;
113import android.app.INotificationManager;
114import android.app.IProcessObserver;
115import android.app.IServiceConnection;
116import android.app.IStopUserCallback;
117import android.app.IUiAutomationConnection;
118import android.app.IUserSwitchObserver;
119import android.app.Instrumentation;
120import android.app.Notification;
121import android.app.NotificationManager;
122import android.app.PendingIntent;
123import android.app.backup.IBackupManager;
124import android.content.ActivityNotFoundException;
125import android.content.BroadcastReceiver;
126import android.content.ClipData;
127import android.content.ComponentCallbacks2;
128import android.content.ComponentName;
129import android.content.ContentProvider;
130import android.content.ContentResolver;
131import android.content.Context;
132import android.content.DialogInterface;
133import android.content.IContentProvider;
134import android.content.IIntentReceiver;
135import android.content.IIntentSender;
136import android.content.Intent;
137import android.content.IntentFilter;
138import android.content.IntentSender;
139import android.content.pm.ActivityInfo;
140import android.content.pm.ApplicationInfo;
141import android.content.pm.ConfigurationInfo;
142import android.content.pm.IPackageDataObserver;
143import android.content.pm.IPackageManager;
144import android.content.pm.InstrumentationInfo;
145import android.content.pm.PackageInfo;
146import android.content.pm.PackageManager;
147import android.content.pm.ParceledListSlice;
148import android.content.pm.UserInfo;
149import android.content.pm.PackageManager.NameNotFoundException;
150import android.content.pm.PathPermission;
151import android.content.pm.ProviderInfo;
152import android.content.pm.ResolveInfo;
153import android.content.pm.ServiceInfo;
154import android.content.res.CompatibilityInfo;
155import android.content.res.Configuration;
156import android.net.Proxy;
157import android.net.ProxyInfo;
158import android.net.Uri;
159import android.os.Binder;
160import android.os.Build;
161import android.os.Bundle;
162import android.os.Debug;
163import android.os.DropBoxManager;
164import android.os.Environment;
165import android.os.FactoryTest;
166import android.os.FileObserver;
167import android.os.FileUtils;
168import android.os.Handler;
169import android.os.IBinder;
170import android.os.IPermissionController;
171import android.os.IRemoteCallback;
172import android.os.IUserManager;
173import android.os.Looper;
174import android.os.Message;
175import android.os.Parcel;
176import android.os.ParcelFileDescriptor;
177import android.os.PowerManagerInternal;
178import android.os.Process;
179import android.os.RemoteCallbackList;
180import android.os.RemoteException;
181import android.os.SELinux;
182import android.os.ServiceManager;
183import android.os.StrictMode;
184import android.os.SystemClock;
185import android.os.SystemProperties;
186import android.os.UpdateLock;
187import android.os.UserHandle;
188import android.os.UserManager;
189import android.provider.Settings;
190import android.text.format.DateUtils;
191import android.text.format.Time;
192import android.util.AtomicFile;
193import android.util.EventLog;
194import android.util.Log;
195import android.util.Pair;
196import android.util.PrintWriterPrinter;
197import android.util.Slog;
198import android.util.SparseArray;
199import android.util.TimeUtils;
200import android.util.Xml;
201import android.view.Gravity;
202import android.view.LayoutInflater;
203import android.view.View;
204import android.view.WindowManager;
205
206import dalvik.system.VMRuntime;
207
208import java.io.BufferedInputStream;
209import java.io.BufferedOutputStream;
210import java.io.DataInputStream;
211import java.io.DataOutputStream;
212import java.io.File;
213import java.io.FileDescriptor;
214import java.io.FileInputStream;
215import java.io.FileNotFoundException;
216import java.io.FileOutputStream;
217import java.io.IOException;
218import java.io.InputStreamReader;
219import java.io.PrintWriter;
220import java.io.StringWriter;
221import java.lang.ref.WeakReference;
222import java.util.ArrayList;
223import java.util.Arrays;
224import java.util.Collections;
225import java.util.Comparator;
226import java.util.HashMap;
227import java.util.HashSet;
228import java.util.Iterator;
229import java.util.List;
230import java.util.Locale;
231import java.util.Map;
232import java.util.Set;
233import java.util.concurrent.atomic.AtomicBoolean;
234import java.util.concurrent.atomic.AtomicLong;
235
236public final class ActivityManagerService extends ActivityManagerNative
237        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
238
239    private static final String USER_DATA_DIR = "/data/user/";
240    // File that stores last updated system version and called preboot receivers
241    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
242
243    static final String TAG = "ActivityManager";
244    static final String TAG_MU = "ActivityManagerServiceMU";
245    static final boolean DEBUG = false;
246    static final boolean localLOGV = DEBUG;
247    static final boolean DEBUG_BACKUP = localLOGV || false;
248    static final boolean DEBUG_BROADCAST = localLOGV || false;
249    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
250    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
251    static final boolean DEBUG_CLEANUP = localLOGV || false;
252    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
253    static final boolean DEBUG_FOCUS = false;
254    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
255    static final boolean DEBUG_MU = localLOGV || false;
256    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
257    static final boolean DEBUG_LRU = localLOGV || false;
258    static final boolean DEBUG_PAUSE = localLOGV || false;
259    static final boolean DEBUG_POWER = localLOGV || false;
260    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
261    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
262    static final boolean DEBUG_PROCESSES = localLOGV || false;
263    static final boolean DEBUG_PROVIDER = localLOGV || false;
264    static final boolean DEBUG_RESULTS = localLOGV || false;
265    static final boolean DEBUG_SERVICE = localLOGV || false;
266    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
267    static final boolean DEBUG_STACK = localLOGV || false;
268    static final boolean DEBUG_SWITCH = localLOGV || false;
269    static final boolean DEBUG_TASKS = localLOGV || false;
270    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
271    static final boolean DEBUG_TRANSITION = localLOGV || false;
272    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
273    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
274    static final boolean DEBUG_VISBILITY = localLOGV || false;
275    static final boolean DEBUG_PSS = localLOGV || false;
276    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
277    static final boolean DEBUG_RECENTS = localLOGV || false;
278    static final boolean VALIDATE_TOKENS = false;
279    static final boolean SHOW_ACTIVITY_START_TIME = true;
280
281    // Control over CPU and battery monitoring.
282    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
283    static final boolean MONITOR_CPU_USAGE = true;
284    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
285    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
286    static final boolean MONITOR_THREAD_CPU_USAGE = false;
287
288    // The flags that are set for all calls we make to the package manager.
289    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
290
291    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
292
293    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
294
295    // Maximum number recent bitmaps to keep in memory.
296    static final int MAX_RECENT_BITMAPS = 3;
297
298    // Amount of time after a call to stopAppSwitches() during which we will
299    // prevent further untrusted switches from happening.
300    static final long APP_SWITCH_DELAY_TIME = 5*1000;
301
302    // How long we wait for a launched process to attach to the activity manager
303    // before we decide it's never going to come up for real.
304    static final int PROC_START_TIMEOUT = 10*1000;
305
306    // How long we wait for a launched process to attach to the activity manager
307    // before we decide it's never going to come up for real, when the process was
308    // started with a wrapper for instrumentation (such as Valgrind) because it
309    // could take much longer than usual.
310    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
311
312    // How long to wait after going idle before forcing apps to GC.
313    static final int GC_TIMEOUT = 5*1000;
314
315    // The minimum amount of time between successive GC requests for a process.
316    static final int GC_MIN_INTERVAL = 60*1000;
317
318    // The minimum amount of time between successive PSS requests for a process.
319    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
320
321    // The minimum amount of time between successive PSS requests for a process
322    // when the request is due to the memory state being lowered.
323    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
324
325    // The rate at which we check for apps using excessive power -- 15 mins.
326    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
327
328    // The minimum sample duration we will allow before deciding we have
329    // enough data on wake locks to start killing things.
330    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
331
332    // The minimum sample duration we will allow before deciding we have
333    // enough data on CPU usage to start killing things.
334    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
335
336    // How long we allow a receiver to run before giving up on it.
337    static final int BROADCAST_FG_TIMEOUT = 10*1000;
338    static final int BROADCAST_BG_TIMEOUT = 60*1000;
339
340    // How long we wait until we timeout on key dispatching.
341    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
342
343    // How long we wait until we timeout on key dispatching during instrumentation.
344    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
345
346    // Amount of time we wait for observers to handle a user switch before
347    // giving up on them and unfreezing the screen.
348    static final int USER_SWITCH_TIMEOUT = 2*1000;
349
350    // Maximum number of users we allow to be running at a time.
351    static final int MAX_RUNNING_USERS = 3;
352
353    // How long to wait in getAssistContextExtras for the activity and foreground services
354    // to respond with the result.
355    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
356
357    // Maximum number of persisted Uri grants a package is allowed
358    static final int MAX_PERSISTED_URI_GRANTS = 128;
359
360    static final int MY_PID = Process.myPid();
361
362    static final String[] EMPTY_STRING_ARRAY = new String[0];
363
364    // How many bytes to write into the dropbox log before truncating
365    static final int DROPBOX_MAX_SIZE = 256 * 1024;
366
367    // Access modes for handleIncomingUser.
368    static final int ALLOW_NON_FULL = 0;
369    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
370    static final int ALLOW_FULL_ONLY = 2;
371
372    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
373
374    // Delay in notifying task stack change listeners (in millis)
375    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
376
377    /** All system services */
378    SystemServiceManager mSystemServiceManager;
379
380    private Installer mInstaller;
381
382    /** Run all ActivityStacks through this */
383    ActivityStackSupervisor mStackSupervisor;
384
385    /** Task stack change listeners. */
386    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
387            new RemoteCallbackList<ITaskStackListener>();
388
389    public IntentFirewall mIntentFirewall;
390
391    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
392    // default actuion automatically.  Important for devices without direct input
393    // devices.
394    private boolean mShowDialogs = true;
395
396    BroadcastQueue mFgBroadcastQueue;
397    BroadcastQueue mBgBroadcastQueue;
398    // Convenient for easy iteration over the queues. Foreground is first
399    // so that dispatch of foreground broadcasts gets precedence.
400    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
401
402    BroadcastQueue broadcastQueueForIntent(Intent intent) {
403        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
404        if (DEBUG_BACKGROUND_BROADCAST) {
405            Slog.i(TAG, "Broadcast intent " + intent + " on "
406                    + (isFg ? "foreground" : "background")
407                    + " queue");
408        }
409        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
410    }
411
412    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
413        for (BroadcastQueue queue : mBroadcastQueues) {
414            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
415            if (r != null) {
416                return r;
417            }
418        }
419        return null;
420    }
421
422    /**
423     * Activity we have told the window manager to have key focus.
424     */
425    ActivityRecord mFocusedActivity = null;
426
427    /**
428     * List of intents that were used to start the most recent tasks.
429     */
430    ArrayList<TaskRecord> mRecentTasks;
431    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
432
433    /**
434     * For addAppTask: cached of the last activity component that was added.
435     */
436    ComponentName mLastAddedTaskComponent;
437
438    /**
439     * For addAppTask: cached of the last activity uid that was added.
440     */
441    int mLastAddedTaskUid;
442
443    /**
444     * For addAppTask: cached of the last ActivityInfo that was added.
445     */
446    ActivityInfo mLastAddedTaskActivity;
447
448    public class PendingAssistExtras extends Binder implements Runnable {
449        public final ActivityRecord activity;
450        public final Bundle extras;
451        public final Intent intent;
452        public final String hint;
453        public final int userHandle;
454        public boolean haveResult = false;
455        public Bundle result = null;
456        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
457                String _hint, int _userHandle) {
458            activity = _activity;
459            extras = _extras;
460            intent = _intent;
461            hint = _hint;
462            userHandle = _userHandle;
463        }
464        @Override
465        public void run() {
466            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
467            synchronized (this) {
468                haveResult = true;
469                notifyAll();
470            }
471        }
472    }
473
474    final ArrayList<PendingAssistExtras> mPendingAssistExtras
475            = new ArrayList<PendingAssistExtras>();
476
477    /**
478     * Process management.
479     */
480    final ProcessList mProcessList = new ProcessList();
481
482    /**
483     * All of the applications we currently have running organized by name.
484     * The keys are strings of the application package name (as
485     * returned by the package manager), and the keys are ApplicationRecord
486     * objects.
487     */
488    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
489
490    /**
491     * Tracking long-term execution of processes to look for abuse and other
492     * bad app behavior.
493     */
494    final ProcessStatsService mProcessStats;
495
496    /**
497     * The currently running isolated processes.
498     */
499    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
500
501    /**
502     * Counter for assigning isolated process uids, to avoid frequently reusing the
503     * same ones.
504     */
505    int mNextIsolatedProcessUid = 0;
506
507    /**
508     * The currently running heavy-weight process, if any.
509     */
510    ProcessRecord mHeavyWeightProcess = null;
511
512    /**
513     * The last time that various processes have crashed.
514     */
515    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
516
517    /**
518     * Information about a process that is currently marked as bad.
519     */
520    static final class BadProcessInfo {
521        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
522            this.time = time;
523            this.shortMsg = shortMsg;
524            this.longMsg = longMsg;
525            this.stack = stack;
526        }
527
528        final long time;
529        final String shortMsg;
530        final String longMsg;
531        final String stack;
532    }
533
534    /**
535     * Set of applications that we consider to be bad, and will reject
536     * incoming broadcasts from (which the user has no control over).
537     * Processes are added to this set when they have crashed twice within
538     * a minimum amount of time; they are removed from it when they are
539     * later restarted (hopefully due to some user action).  The value is the
540     * time it was added to the list.
541     */
542    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
543
544    /**
545     * All of the processes we currently have running organized by pid.
546     * The keys are the pid running the application.
547     *
548     * <p>NOTE: This object is protected by its own lock, NOT the global
549     * activity manager lock!
550     */
551    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
552
553    /**
554     * All of the processes that have been forced to be foreground.  The key
555     * is the pid of the caller who requested it (we hold a death
556     * link on it).
557     */
558    abstract class ForegroundToken implements IBinder.DeathRecipient {
559        int pid;
560        IBinder token;
561    }
562    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
563
564    /**
565     * List of records for processes that someone had tried to start before the
566     * system was ready.  We don't start them at that point, but ensure they
567     * are started by the time booting is complete.
568     */
569    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
570
571    /**
572     * List of persistent applications that are in the process
573     * of being started.
574     */
575    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
576
577    /**
578     * Processes that are being forcibly torn down.
579     */
580    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
581
582    /**
583     * List of running applications, sorted by recent usage.
584     * The first entry in the list is the least recently used.
585     */
586    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
587
588    /**
589     * Where in mLruProcesses that the processes hosting activities start.
590     */
591    int mLruProcessActivityStart = 0;
592
593    /**
594     * Where in mLruProcesses that the processes hosting services start.
595     * This is after (lower index) than mLruProcessesActivityStart.
596     */
597    int mLruProcessServiceStart = 0;
598
599    /**
600     * List of processes that should gc as soon as things are idle.
601     */
602    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
603
604    /**
605     * Processes we want to collect PSS data from.
606     */
607    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
608
609    /**
610     * Last time we requested PSS data of all processes.
611     */
612    long mLastFullPssTime = SystemClock.uptimeMillis();
613
614    /**
615     * If set, the next time we collect PSS data we should do a full collection
616     * with data from native processes and the kernel.
617     */
618    boolean mFullPssPending = false;
619
620    /**
621     * This is the process holding what we currently consider to be
622     * the "home" activity.
623     */
624    ProcessRecord mHomeProcess;
625
626    /**
627     * This is the process holding the activity the user last visited that
628     * is in a different process from the one they are currently in.
629     */
630    ProcessRecord mPreviousProcess;
631
632    /**
633     * The time at which the previous process was last visible.
634     */
635    long mPreviousProcessVisibleTime;
636
637    /**
638     * Which uses have been started, so are allowed to run code.
639     */
640    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
641
642    /**
643     * LRU list of history of current users.  Most recently current is at the end.
644     */
645    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
646
647    /**
648     * Constant array of the users that are currently started.
649     */
650    int[] mStartedUserArray = new int[] { 0 };
651
652    /**
653     * Registered observers of the user switching mechanics.
654     */
655    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
656            = new RemoteCallbackList<IUserSwitchObserver>();
657
658    /**
659     * Currently active user switch.
660     */
661    Object mCurUserSwitchCallback;
662
663    /**
664     * Packages that the user has asked to have run in screen size
665     * compatibility mode instead of filling the screen.
666     */
667    final CompatModePackages mCompatModePackages;
668
669    /**
670     * Set of IntentSenderRecord objects that are currently active.
671     */
672    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
673            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
674
675    /**
676     * Fingerprints (hashCode()) of stack traces that we've
677     * already logged DropBox entries for.  Guarded by itself.  If
678     * something (rogue user app) forces this over
679     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
680     */
681    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
682    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
683
684    /**
685     * Strict Mode background batched logging state.
686     *
687     * The string buffer is guarded by itself, and its lock is also
688     * used to determine if another batched write is already
689     * in-flight.
690     */
691    private final StringBuilder mStrictModeBuffer = new StringBuilder();
692
693    /**
694     * Keeps track of all IIntentReceivers that have been registered for
695     * broadcasts.  Hash keys are the receiver IBinder, hash value is
696     * a ReceiverList.
697     */
698    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
699            new HashMap<IBinder, ReceiverList>();
700
701    /**
702     * Resolver for broadcast intents to registered receivers.
703     * Holds BroadcastFilter (subclass of IntentFilter).
704     */
705    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
706            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
707        @Override
708        protected boolean allowFilterResult(
709                BroadcastFilter filter, List<BroadcastFilter> dest) {
710            IBinder target = filter.receiverList.receiver.asBinder();
711            for (int i=dest.size()-1; i>=0; i--) {
712                if (dest.get(i).receiverList.receiver.asBinder() == target) {
713                    return false;
714                }
715            }
716            return true;
717        }
718
719        @Override
720        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
721            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
722                    || userId == filter.owningUserId) {
723                return super.newResult(filter, match, userId);
724            }
725            return null;
726        }
727
728        @Override
729        protected BroadcastFilter[] newArray(int size) {
730            return new BroadcastFilter[size];
731        }
732
733        @Override
734        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
735            return packageName.equals(filter.packageName);
736        }
737    };
738
739    /**
740     * State of all active sticky broadcasts per user.  Keys are the action of the
741     * sticky Intent, values are an ArrayList of all broadcasted intents with
742     * that action (which should usually be one).  The SparseArray is keyed
743     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
744     * for stickies that are sent to all users.
745     */
746    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
747            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
748
749    final ActiveServices mServices;
750
751    /**
752     * Backup/restore process management
753     */
754    String mBackupAppName = null;
755    BackupRecord mBackupTarget = null;
756
757    final ProviderMap mProviderMap;
758
759    /**
760     * List of content providers who have clients waiting for them.  The
761     * application is currently being launched and the provider will be
762     * removed from this list once it is published.
763     */
764    final ArrayList<ContentProviderRecord> mLaunchingProviders
765            = new ArrayList<ContentProviderRecord>();
766
767    /**
768     * File storing persisted {@link #mGrantedUriPermissions}.
769     */
770    private final AtomicFile mGrantFile;
771
772    /** XML constants used in {@link #mGrantFile} */
773    private static final String TAG_URI_GRANTS = "uri-grants";
774    private static final String TAG_URI_GRANT = "uri-grant";
775    private static final String ATTR_USER_HANDLE = "userHandle";
776    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
777    private static final String ATTR_TARGET_USER_ID = "targetUserId";
778    private static final String ATTR_SOURCE_PKG = "sourcePkg";
779    private static final String ATTR_TARGET_PKG = "targetPkg";
780    private static final String ATTR_URI = "uri";
781    private static final String ATTR_MODE_FLAGS = "modeFlags";
782    private static final String ATTR_CREATED_TIME = "createdTime";
783    private static final String ATTR_PREFIX = "prefix";
784
785    /**
786     * Global set of specific {@link Uri} permissions that have been granted.
787     * This optimized lookup structure maps from {@link UriPermission#targetUid}
788     * to {@link UriPermission#uri} to {@link UriPermission}.
789     */
790    @GuardedBy("this")
791    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
792            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
793
794    public static class GrantUri {
795        public final int sourceUserId;
796        public final Uri uri;
797        public boolean prefix;
798
799        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
800            this.sourceUserId = sourceUserId;
801            this.uri = uri;
802            this.prefix = prefix;
803        }
804
805        @Override
806        public int hashCode() {
807            int hashCode = 1;
808            hashCode = 31 * hashCode + sourceUserId;
809            hashCode = 31 * hashCode + uri.hashCode();
810            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
811            return hashCode;
812        }
813
814        @Override
815        public boolean equals(Object o) {
816            if (o instanceof GrantUri) {
817                GrantUri other = (GrantUri) o;
818                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
819                        && prefix == other.prefix;
820            }
821            return false;
822        }
823
824        @Override
825        public String toString() {
826            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
827            if (prefix) result += " [prefix]";
828            return result;
829        }
830
831        public String toSafeString() {
832            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
833            if (prefix) result += " [prefix]";
834            return result;
835        }
836
837        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
838            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
839                    ContentProvider.getUriWithoutUserId(uri), false);
840        }
841    }
842
843    CoreSettingsObserver mCoreSettingsObserver;
844
845    /**
846     * Thread-local storage used to carry caller permissions over through
847     * indirect content-provider access.
848     */
849    private class Identity {
850        public final IBinder token;
851        public final int pid;
852        public final int uid;
853
854        Identity(IBinder _token, int _pid, int _uid) {
855            token = _token;
856            pid = _pid;
857            uid = _uid;
858        }
859    }
860
861    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
862
863    /**
864     * All information we have collected about the runtime performance of
865     * any user id that can impact battery performance.
866     */
867    final BatteryStatsService mBatteryStatsService;
868
869    /**
870     * Information about component usage
871     */
872    UsageStatsManagerInternal mUsageStatsService;
873
874    /**
875     * Information about and control over application operations
876     */
877    final AppOpsService mAppOpsService;
878
879    /**
880     * Save recent tasks information across reboots.
881     */
882    final TaskPersister mTaskPersister;
883
884    /**
885     * Current configuration information.  HistoryRecord objects are given
886     * a reference to this object to indicate which configuration they are
887     * currently running in, so this object must be kept immutable.
888     */
889    Configuration mConfiguration = new Configuration();
890
891    /**
892     * Current sequencing integer of the configuration, for skipping old
893     * configurations.
894     */
895    int mConfigurationSeq = 0;
896
897    /**
898     * Hardware-reported OpenGLES version.
899     */
900    final int GL_ES_VERSION;
901
902    /**
903     * List of initialization arguments to pass to all processes when binding applications to them.
904     * For example, references to the commonly used services.
905     */
906    HashMap<String, IBinder> mAppBindArgs;
907
908    /**
909     * Temporary to avoid allocations.  Protected by main lock.
910     */
911    final StringBuilder mStringBuilder = new StringBuilder(256);
912
913    /**
914     * Used to control how we initialize the service.
915     */
916    ComponentName mTopComponent;
917    String mTopAction = Intent.ACTION_MAIN;
918    String mTopData;
919    boolean mProcessesReady = false;
920    boolean mSystemReady = false;
921    boolean mBooting = false;
922    boolean mCallFinishBooting = false;
923    boolean mBootAnimationComplete = false;
924    boolean mWaitingUpdate = false;
925    boolean mDidUpdate = false;
926    boolean mOnBattery = false;
927    boolean mLaunchWarningShown = false;
928
929    Context mContext;
930
931    int mFactoryTest;
932
933    boolean mCheckedForSetup;
934
935    /**
936     * The time at which we will allow normal application switches again,
937     * after a call to {@link #stopAppSwitches()}.
938     */
939    long mAppSwitchesAllowedTime;
940
941    /**
942     * This is set to true after the first switch after mAppSwitchesAllowedTime
943     * is set; any switches after that will clear the time.
944     */
945    boolean mDidAppSwitch;
946
947    /**
948     * Last time (in realtime) at which we checked for power usage.
949     */
950    long mLastPowerCheckRealtime;
951
952    /**
953     * Last time (in uptime) at which we checked for power usage.
954     */
955    long mLastPowerCheckUptime;
956
957    /**
958     * Set while we are wanting to sleep, to prevent any
959     * activities from being started/resumed.
960     */
961    private boolean mSleeping = false;
962
963    /**
964     * Set while we are running a voice interaction.  This overrides
965     * sleeping while it is active.
966     */
967    private boolean mRunningVoice = false;
968
969    /**
970     * State of external calls telling us if the device is awake or asleep.
971     */
972    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
973
974    static final int LOCK_SCREEN_HIDDEN = 0;
975    static final int LOCK_SCREEN_LEAVING = 1;
976    static final int LOCK_SCREEN_SHOWN = 2;
977    /**
978     * State of external call telling us if the lock screen is shown.
979     */
980    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
981
982    /**
983     * Set if we are shutting down the system, similar to sleeping.
984     */
985    boolean mShuttingDown = false;
986
987    /**
988     * Current sequence id for oom_adj computation traversal.
989     */
990    int mAdjSeq = 0;
991
992    /**
993     * Current sequence id for process LRU updating.
994     */
995    int mLruSeq = 0;
996
997    /**
998     * Keep track of the non-cached/empty process we last found, to help
999     * determine how to distribute cached/empty processes next time.
1000     */
1001    int mNumNonCachedProcs = 0;
1002
1003    /**
1004     * Keep track of the number of cached hidden procs, to balance oom adj
1005     * distribution between those and empty procs.
1006     */
1007    int mNumCachedHiddenProcs = 0;
1008
1009    /**
1010     * Keep track of the number of service processes we last found, to
1011     * determine on the next iteration which should be B services.
1012     */
1013    int mNumServiceProcs = 0;
1014    int mNewNumAServiceProcs = 0;
1015    int mNewNumServiceProcs = 0;
1016
1017    /**
1018     * Allow the current computed overall memory level of the system to go down?
1019     * This is set to false when we are killing processes for reasons other than
1020     * memory management, so that the now smaller process list will not be taken as
1021     * an indication that memory is tighter.
1022     */
1023    boolean mAllowLowerMemLevel = false;
1024
1025    /**
1026     * The last computed memory level, for holding when we are in a state that
1027     * processes are going away for other reasons.
1028     */
1029    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1030
1031    /**
1032     * The last total number of process we have, to determine if changes actually look
1033     * like a shrinking number of process due to lower RAM.
1034     */
1035    int mLastNumProcesses;
1036
1037    /**
1038     * The uptime of the last time we performed idle maintenance.
1039     */
1040    long mLastIdleTime = SystemClock.uptimeMillis();
1041
1042    /**
1043     * Total time spent with RAM that has been added in the past since the last idle time.
1044     */
1045    long mLowRamTimeSinceLastIdle = 0;
1046
1047    /**
1048     * If RAM is currently low, when that horrible situation started.
1049     */
1050    long mLowRamStartTime = 0;
1051
1052    /**
1053     * For reporting to battery stats the current top application.
1054     */
1055    private String mCurResumedPackage = null;
1056    private int mCurResumedUid = -1;
1057
1058    /**
1059     * For reporting to battery stats the apps currently running foreground
1060     * service.  The ProcessMap is package/uid tuples; each of these contain
1061     * an array of the currently foreground processes.
1062     */
1063    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1064            = new ProcessMap<ArrayList<ProcessRecord>>();
1065
1066    /**
1067     * This is set if we had to do a delayed dexopt of an app before launching
1068     * it, to increase the ANR timeouts in that case.
1069     */
1070    boolean mDidDexOpt;
1071
1072    /**
1073     * Set if the systemServer made a call to enterSafeMode.
1074     */
1075    boolean mSafeMode;
1076
1077    String mDebugApp = null;
1078    boolean mWaitForDebugger = false;
1079    boolean mDebugTransient = false;
1080    String mOrigDebugApp = null;
1081    boolean mOrigWaitForDebugger = false;
1082    boolean mAlwaysFinishActivities = false;
1083    IActivityController mController = null;
1084    String mProfileApp = null;
1085    ProcessRecord mProfileProc = null;
1086    String mProfileFile;
1087    ParcelFileDescriptor mProfileFd;
1088    int mSamplingInterval = 0;
1089    boolean mAutoStopProfiler = false;
1090    int mProfileType = 0;
1091    String mOpenGlTraceApp = null;
1092
1093    static class ProcessChangeItem {
1094        static final int CHANGE_ACTIVITIES = 1<<0;
1095        static final int CHANGE_PROCESS_STATE = 1<<1;
1096        int changes;
1097        int uid;
1098        int pid;
1099        int processState;
1100        boolean foregroundActivities;
1101    }
1102
1103    final RemoteCallbackList<IProcessObserver> mProcessObservers
1104            = new RemoteCallbackList<IProcessObserver>();
1105    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1106
1107    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1108            = new ArrayList<ProcessChangeItem>();
1109    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1110            = new ArrayList<ProcessChangeItem>();
1111
1112    /**
1113     * Runtime CPU use collection thread.  This object's lock is used to
1114     * perform synchronization with the thread (notifying it to run).
1115     */
1116    final Thread mProcessCpuThread;
1117
1118    /**
1119     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1120     * Must acquire this object's lock when accessing it.
1121     * NOTE: this lock will be held while doing long operations (trawling
1122     * through all processes in /proc), so it should never be acquired by
1123     * any critical paths such as when holding the main activity manager lock.
1124     */
1125    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1126            MONITOR_THREAD_CPU_USAGE);
1127    final AtomicLong mLastCpuTime = new AtomicLong(0);
1128    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1129
1130    long mLastWriteTime = 0;
1131
1132    /**
1133     * Used to retain an update lock when the foreground activity is in
1134     * immersive mode.
1135     */
1136    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1137
1138    /**
1139     * Set to true after the system has finished booting.
1140     */
1141    boolean mBooted = false;
1142
1143    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1144    int mProcessLimitOverride = -1;
1145
1146    WindowManagerService mWindowManager;
1147
1148    final ActivityThread mSystemThread;
1149
1150    // Holds the current foreground user's id
1151    int mCurrentUserId = 0;
1152    // Holds the target user's id during a user switch
1153    int mTargetUserId = UserHandle.USER_NULL;
1154    // If there are multiple profiles for the current user, their ids are here
1155    // Currently only the primary user can have managed profiles
1156    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1157
1158    /**
1159     * Mapping from each known user ID to the profile group ID it is associated with.
1160     */
1161    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1162
1163    private UserManagerService mUserManager;
1164
1165    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1166        final ProcessRecord mApp;
1167        final int mPid;
1168        final IApplicationThread mAppThread;
1169
1170        AppDeathRecipient(ProcessRecord app, int pid,
1171                IApplicationThread thread) {
1172            if (localLOGV) Slog.v(
1173                TAG, "New death recipient " + this
1174                + " for thread " + thread.asBinder());
1175            mApp = app;
1176            mPid = pid;
1177            mAppThread = thread;
1178        }
1179
1180        @Override
1181        public void binderDied() {
1182            if (localLOGV) Slog.v(
1183                TAG, "Death received in " + this
1184                + " for thread " + mAppThread.asBinder());
1185            synchronized(ActivityManagerService.this) {
1186                appDiedLocked(mApp, mPid, mAppThread);
1187            }
1188        }
1189    }
1190
1191    static final int SHOW_ERROR_MSG = 1;
1192    static final int SHOW_NOT_RESPONDING_MSG = 2;
1193    static final int SHOW_FACTORY_ERROR_MSG = 3;
1194    static final int UPDATE_CONFIGURATION_MSG = 4;
1195    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1196    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1197    static final int SERVICE_TIMEOUT_MSG = 12;
1198    static final int UPDATE_TIME_ZONE = 13;
1199    static final int SHOW_UID_ERROR_MSG = 14;
1200    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1201    static final int PROC_START_TIMEOUT_MSG = 20;
1202    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1203    static final int KILL_APPLICATION_MSG = 22;
1204    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1205    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1206    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1207    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1208    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1209    static final int CLEAR_DNS_CACHE_MSG = 28;
1210    static final int UPDATE_HTTP_PROXY_MSG = 29;
1211    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1212    static final int DISPATCH_PROCESSES_CHANGED = 31;
1213    static final int DISPATCH_PROCESS_DIED = 32;
1214    static final int REPORT_MEM_USAGE_MSG = 33;
1215    static final int REPORT_USER_SWITCH_MSG = 34;
1216    static final int CONTINUE_USER_SWITCH_MSG = 35;
1217    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1218    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1219    static final int PERSIST_URI_GRANTS_MSG = 38;
1220    static final int REQUEST_ALL_PSS_MSG = 39;
1221    static final int START_PROFILES_MSG = 40;
1222    static final int UPDATE_TIME = 41;
1223    static final int SYSTEM_USER_START_MSG = 42;
1224    static final int SYSTEM_USER_CURRENT_MSG = 43;
1225    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1226    static final int FINISH_BOOTING_MSG = 45;
1227    static final int START_USER_SWITCH_MSG = 46;
1228    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1229    static final int DISMISS_DIALOG_MSG = 48;
1230    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1231
1232    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1233    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1234    static final int FIRST_COMPAT_MODE_MSG = 300;
1235    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1236
1237    CompatModeDialog mCompatModeDialog;
1238    long mLastMemUsageReportTime = 0;
1239
1240    /**
1241     * Flag whether the current user is a "monkey", i.e. whether
1242     * the UI is driven by a UI automation tool.
1243     */
1244    private boolean mUserIsMonkey;
1245
1246    /** Flag whether the device has a Recents UI */
1247    boolean mHasRecents;
1248
1249    /** The dimensions of the thumbnails in the Recents UI. */
1250    int mThumbnailWidth;
1251    int mThumbnailHeight;
1252
1253    final ServiceThread mHandlerThread;
1254    final MainHandler mHandler;
1255
1256    final class MainHandler extends Handler {
1257        public MainHandler(Looper looper) {
1258            super(looper, null, true);
1259        }
1260
1261        @Override
1262        public void handleMessage(Message msg) {
1263            switch (msg.what) {
1264            case SHOW_ERROR_MSG: {
1265                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1266                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1267                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1268                synchronized (ActivityManagerService.this) {
1269                    ProcessRecord proc = (ProcessRecord)data.get("app");
1270                    AppErrorResult res = (AppErrorResult) data.get("result");
1271                    if (proc != null && proc.crashDialog != null) {
1272                        Slog.e(TAG, "App already has crash dialog: " + proc);
1273                        if (res != null) {
1274                            res.set(0);
1275                        }
1276                        return;
1277                    }
1278                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1279                            >= Process.FIRST_APPLICATION_UID
1280                            && proc.pid != MY_PID);
1281                    for (int userId : mCurrentProfileIds) {
1282                        isBackground &= (proc.userId != userId);
1283                    }
1284                    if (isBackground && !showBackground) {
1285                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1286                        if (res != null) {
1287                            res.set(0);
1288                        }
1289                        return;
1290                    }
1291                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1292                        Dialog d = new AppErrorDialog(mContext,
1293                                ActivityManagerService.this, res, proc);
1294                        d.show();
1295                        proc.crashDialog = d;
1296                    } else {
1297                        // The device is asleep, so just pretend that the user
1298                        // saw a crash dialog and hit "force quit".
1299                        if (res != null) {
1300                            res.set(0);
1301                        }
1302                    }
1303                }
1304
1305                ensureBootCompleted();
1306            } break;
1307            case SHOW_NOT_RESPONDING_MSG: {
1308                synchronized (ActivityManagerService.this) {
1309                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1310                    ProcessRecord proc = (ProcessRecord)data.get("app");
1311                    if (proc != null && proc.anrDialog != null) {
1312                        Slog.e(TAG, "App already has anr dialog: " + proc);
1313                        return;
1314                    }
1315
1316                    Intent intent = new Intent("android.intent.action.ANR");
1317                    if (!mProcessesReady) {
1318                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1319                                | Intent.FLAG_RECEIVER_FOREGROUND);
1320                    }
1321                    broadcastIntentLocked(null, null, intent,
1322                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1323                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1324
1325                    if (mShowDialogs) {
1326                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1327                                mContext, proc, (ActivityRecord)data.get("activity"),
1328                                msg.arg1 != 0);
1329                        d.show();
1330                        proc.anrDialog = d;
1331                    } else {
1332                        // Just kill the app if there is no dialog to be shown.
1333                        killAppAtUsersRequest(proc, null);
1334                    }
1335                }
1336
1337                ensureBootCompleted();
1338            } break;
1339            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1340                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1341                synchronized (ActivityManagerService.this) {
1342                    ProcessRecord proc = (ProcessRecord) data.get("app");
1343                    if (proc == null) {
1344                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1345                        break;
1346                    }
1347                    if (proc.crashDialog != null) {
1348                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1349                        return;
1350                    }
1351                    AppErrorResult res = (AppErrorResult) data.get("result");
1352                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1353                        Dialog d = new StrictModeViolationDialog(mContext,
1354                                ActivityManagerService.this, res, proc);
1355                        d.show();
1356                        proc.crashDialog = d;
1357                    } else {
1358                        // The device is asleep, so just pretend that the user
1359                        // saw a crash dialog and hit "force quit".
1360                        res.set(0);
1361                    }
1362                }
1363                ensureBootCompleted();
1364            } break;
1365            case SHOW_FACTORY_ERROR_MSG: {
1366                Dialog d = new FactoryErrorDialog(
1367                    mContext, msg.getData().getCharSequence("msg"));
1368                d.show();
1369                ensureBootCompleted();
1370            } break;
1371            case UPDATE_CONFIGURATION_MSG: {
1372                final ContentResolver resolver = mContext.getContentResolver();
1373                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1374            } break;
1375            case GC_BACKGROUND_PROCESSES_MSG: {
1376                synchronized (ActivityManagerService.this) {
1377                    performAppGcsIfAppropriateLocked();
1378                }
1379            } break;
1380            case WAIT_FOR_DEBUGGER_MSG: {
1381                synchronized (ActivityManagerService.this) {
1382                    ProcessRecord app = (ProcessRecord)msg.obj;
1383                    if (msg.arg1 != 0) {
1384                        if (!app.waitedForDebugger) {
1385                            Dialog d = new AppWaitingForDebuggerDialog(
1386                                    ActivityManagerService.this,
1387                                    mContext, app);
1388                            app.waitDialog = d;
1389                            app.waitedForDebugger = true;
1390                            d.show();
1391                        }
1392                    } else {
1393                        if (app.waitDialog != null) {
1394                            app.waitDialog.dismiss();
1395                            app.waitDialog = null;
1396                        }
1397                    }
1398                }
1399            } break;
1400            case SERVICE_TIMEOUT_MSG: {
1401                if (mDidDexOpt) {
1402                    mDidDexOpt = false;
1403                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1404                    nmsg.obj = msg.obj;
1405                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1406                    return;
1407                }
1408                mServices.serviceTimeout((ProcessRecord)msg.obj);
1409            } break;
1410            case UPDATE_TIME_ZONE: {
1411                synchronized (ActivityManagerService.this) {
1412                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1413                        ProcessRecord r = mLruProcesses.get(i);
1414                        if (r.thread != null) {
1415                            try {
1416                                r.thread.updateTimeZone();
1417                            } catch (RemoteException ex) {
1418                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1419                            }
1420                        }
1421                    }
1422                }
1423            } break;
1424            case CLEAR_DNS_CACHE_MSG: {
1425                synchronized (ActivityManagerService.this) {
1426                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1427                        ProcessRecord r = mLruProcesses.get(i);
1428                        if (r.thread != null) {
1429                            try {
1430                                r.thread.clearDnsCache();
1431                            } catch (RemoteException ex) {
1432                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1433                            }
1434                        }
1435                    }
1436                }
1437            } break;
1438            case UPDATE_HTTP_PROXY_MSG: {
1439                ProxyInfo proxy = (ProxyInfo)msg.obj;
1440                String host = "";
1441                String port = "";
1442                String exclList = "";
1443                Uri pacFileUrl = Uri.EMPTY;
1444                if (proxy != null) {
1445                    host = proxy.getHost();
1446                    port = Integer.toString(proxy.getPort());
1447                    exclList = proxy.getExclusionListAsString();
1448                    pacFileUrl = proxy.getPacFileUrl();
1449                }
1450                synchronized (ActivityManagerService.this) {
1451                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1452                        ProcessRecord r = mLruProcesses.get(i);
1453                        if (r.thread != null) {
1454                            try {
1455                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1456                            } catch (RemoteException ex) {
1457                                Slog.w(TAG, "Failed to update http proxy for: " +
1458                                        r.info.processName);
1459                            }
1460                        }
1461                    }
1462                }
1463            } break;
1464            case SHOW_UID_ERROR_MSG: {
1465                if (mShowDialogs) {
1466                    AlertDialog d = new BaseErrorDialog(mContext);
1467                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1468                    d.setCancelable(false);
1469                    d.setTitle(mContext.getText(R.string.android_system_label));
1470                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1471                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1472                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1473                    d.show();
1474                }
1475            } break;
1476            case SHOW_FINGERPRINT_ERROR_MSG: {
1477                if (mShowDialogs) {
1478                    AlertDialog d = new BaseErrorDialog(mContext);
1479                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1480                    d.setCancelable(false);
1481                    d.setTitle(mContext.getText(R.string.android_system_label));
1482                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1483                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1484                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1485                    d.show();
1486                }
1487            } break;
1488            case PROC_START_TIMEOUT_MSG: {
1489                if (mDidDexOpt) {
1490                    mDidDexOpt = false;
1491                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1492                    nmsg.obj = msg.obj;
1493                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1494                    return;
1495                }
1496                ProcessRecord app = (ProcessRecord)msg.obj;
1497                synchronized (ActivityManagerService.this) {
1498                    processStartTimedOutLocked(app);
1499                }
1500            } break;
1501            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1502                synchronized (ActivityManagerService.this) {
1503                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1504                }
1505            } break;
1506            case KILL_APPLICATION_MSG: {
1507                synchronized (ActivityManagerService.this) {
1508                    int appid = msg.arg1;
1509                    boolean restart = (msg.arg2 == 1);
1510                    Bundle bundle = (Bundle)msg.obj;
1511                    String pkg = bundle.getString("pkg");
1512                    String reason = bundle.getString("reason");
1513                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1514                            false, UserHandle.USER_ALL, reason);
1515                }
1516            } break;
1517            case FINALIZE_PENDING_INTENT_MSG: {
1518                ((PendingIntentRecord)msg.obj).completeFinalize();
1519            } break;
1520            case POST_HEAVY_NOTIFICATION_MSG: {
1521                INotificationManager inm = NotificationManager.getService();
1522                if (inm == null) {
1523                    return;
1524                }
1525
1526                ActivityRecord root = (ActivityRecord)msg.obj;
1527                ProcessRecord process = root.app;
1528                if (process == null) {
1529                    return;
1530                }
1531
1532                try {
1533                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1534                    String text = mContext.getString(R.string.heavy_weight_notification,
1535                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1536                    Notification notification = new Notification();
1537                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1538                    notification.when = 0;
1539                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1540                    notification.tickerText = text;
1541                    notification.defaults = 0; // please be quiet
1542                    notification.sound = null;
1543                    notification.vibrate = null;
1544                    notification.color = mContext.getResources().getColor(
1545                            com.android.internal.R.color.system_notification_accent_color);
1546                    notification.setLatestEventInfo(context, text,
1547                            mContext.getText(R.string.heavy_weight_notification_detail),
1548                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1549                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1550                                    new UserHandle(root.userId)));
1551
1552                    try {
1553                        int[] outId = new int[1];
1554                        inm.enqueueNotificationWithTag("android", "android", null,
1555                                R.string.heavy_weight_notification,
1556                                notification, outId, root.userId);
1557                    } catch (RuntimeException e) {
1558                        Slog.w(ActivityManagerService.TAG,
1559                                "Error showing notification for heavy-weight app", e);
1560                    } catch (RemoteException e) {
1561                    }
1562                } catch (NameNotFoundException e) {
1563                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1564                }
1565            } break;
1566            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1567                INotificationManager inm = NotificationManager.getService();
1568                if (inm == null) {
1569                    return;
1570                }
1571                try {
1572                    inm.cancelNotificationWithTag("android", null,
1573                            R.string.heavy_weight_notification,  msg.arg1);
1574                } catch (RuntimeException e) {
1575                    Slog.w(ActivityManagerService.TAG,
1576                            "Error canceling notification for service", e);
1577                } catch (RemoteException e) {
1578                }
1579            } break;
1580            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1581                synchronized (ActivityManagerService.this) {
1582                    checkExcessivePowerUsageLocked(true);
1583                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1584                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1585                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1586                }
1587            } break;
1588            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1589                synchronized (ActivityManagerService.this) {
1590                    ActivityRecord ar = (ActivityRecord)msg.obj;
1591                    if (mCompatModeDialog != null) {
1592                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1593                                ar.info.applicationInfo.packageName)) {
1594                            return;
1595                        }
1596                        mCompatModeDialog.dismiss();
1597                        mCompatModeDialog = null;
1598                    }
1599                    if (ar != null && false) {
1600                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1601                                ar.packageName)) {
1602                            int mode = mCompatModePackages.computeCompatModeLocked(
1603                                    ar.info.applicationInfo);
1604                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1605                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1606                                mCompatModeDialog = new CompatModeDialog(
1607                                        ActivityManagerService.this, mContext,
1608                                        ar.info.applicationInfo);
1609                                mCompatModeDialog.show();
1610                            }
1611                        }
1612                    }
1613                }
1614                break;
1615            }
1616            case DISPATCH_PROCESSES_CHANGED: {
1617                dispatchProcessesChanged();
1618                break;
1619            }
1620            case DISPATCH_PROCESS_DIED: {
1621                final int pid = msg.arg1;
1622                final int uid = msg.arg2;
1623                dispatchProcessDied(pid, uid);
1624                break;
1625            }
1626            case REPORT_MEM_USAGE_MSG: {
1627                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1628                Thread thread = new Thread() {
1629                    @Override public void run() {
1630                        reportMemUsage(memInfos);
1631                    }
1632                };
1633                thread.start();
1634                break;
1635            }
1636            case START_USER_SWITCH_MSG: {
1637                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1638                break;
1639            }
1640            case REPORT_USER_SWITCH_MSG: {
1641                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1642                break;
1643            }
1644            case CONTINUE_USER_SWITCH_MSG: {
1645                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1646                break;
1647            }
1648            case USER_SWITCH_TIMEOUT_MSG: {
1649                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1650                break;
1651            }
1652            case IMMERSIVE_MODE_LOCK_MSG: {
1653                final boolean nextState = (msg.arg1 != 0);
1654                if (mUpdateLock.isHeld() != nextState) {
1655                    if (DEBUG_IMMERSIVE) {
1656                        final ActivityRecord r = (ActivityRecord) msg.obj;
1657                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1658                    }
1659                    if (nextState) {
1660                        mUpdateLock.acquire();
1661                    } else {
1662                        mUpdateLock.release();
1663                    }
1664                }
1665                break;
1666            }
1667            case PERSIST_URI_GRANTS_MSG: {
1668                writeGrantedUriPermissions();
1669                break;
1670            }
1671            case REQUEST_ALL_PSS_MSG: {
1672                synchronized (ActivityManagerService.this) {
1673                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1674                }
1675                break;
1676            }
1677            case START_PROFILES_MSG: {
1678                synchronized (ActivityManagerService.this) {
1679                    startProfilesLocked();
1680                }
1681                break;
1682            }
1683            case UPDATE_TIME: {
1684                synchronized (ActivityManagerService.this) {
1685                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1686                        ProcessRecord r = mLruProcesses.get(i);
1687                        if (r.thread != null) {
1688                            try {
1689                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1690                            } catch (RemoteException ex) {
1691                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1692                            }
1693                        }
1694                    }
1695                }
1696                break;
1697            }
1698            case SYSTEM_USER_START_MSG: {
1699                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1700                        Integer.toString(msg.arg1), msg.arg1);
1701                mSystemServiceManager.startUser(msg.arg1);
1702                break;
1703            }
1704            case SYSTEM_USER_CURRENT_MSG: {
1705                mBatteryStatsService.noteEvent(
1706                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1707                        Integer.toString(msg.arg2), msg.arg2);
1708                mBatteryStatsService.noteEvent(
1709                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1710                        Integer.toString(msg.arg1), msg.arg1);
1711                mSystemServiceManager.switchUser(msg.arg1);
1712                break;
1713            }
1714            case ENTER_ANIMATION_COMPLETE_MSG: {
1715                synchronized (ActivityManagerService.this) {
1716                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1717                    if (r != null && r.app != null && r.app.thread != null) {
1718                        try {
1719                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1720                        } catch (RemoteException e) {
1721                        }
1722                    }
1723                }
1724                break;
1725            }
1726            case FINISH_BOOTING_MSG: {
1727                if (msg.arg1 != 0) {
1728                    finishBooting();
1729                }
1730                if (msg.arg2 != 0) {
1731                    enableScreenAfterBoot();
1732                }
1733                break;
1734            }
1735            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1736                try {
1737                    Locale l = (Locale) msg.obj;
1738                    IBinder service = ServiceManager.getService("mount");
1739                    IMountService mountService = IMountService.Stub.asInterface(service);
1740                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1741                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1742                } catch (RemoteException e) {
1743                    Log.e(TAG, "Error storing locale for decryption UI", e);
1744                }
1745                break;
1746            }
1747            case DISMISS_DIALOG_MSG: {
1748                final Dialog d = (Dialog) msg.obj;
1749                d.dismiss();
1750                break;
1751            }
1752            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1753                synchronized (ActivityManagerService.this) {
1754                    int i = mTaskStackListeners.beginBroadcast();
1755                    while (i > 0) {
1756                        i--;
1757                        try {
1758                            // Make a one-way callback to the listener
1759                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1760                        } catch (RemoteException e){
1761                            // Handled by the RemoteCallbackList
1762                        }
1763                    }
1764                    mTaskStackListeners.finishBroadcast();
1765                }
1766                break;
1767            }
1768            }
1769        }
1770    };
1771
1772    static final int COLLECT_PSS_BG_MSG = 1;
1773
1774    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1775        @Override
1776        public void handleMessage(Message msg) {
1777            switch (msg.what) {
1778            case COLLECT_PSS_BG_MSG: {
1779                long start = SystemClock.uptimeMillis();
1780                MemInfoReader memInfo = null;
1781                synchronized (ActivityManagerService.this) {
1782                    if (mFullPssPending) {
1783                        mFullPssPending = false;
1784                        memInfo = new MemInfoReader();
1785                    }
1786                }
1787                if (memInfo != null) {
1788                    updateCpuStatsNow();
1789                    long nativeTotalPss = 0;
1790                    synchronized (mProcessCpuTracker) {
1791                        final int N = mProcessCpuTracker.countStats();
1792                        for (int j=0; j<N; j++) {
1793                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1794                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1795                                // This is definitely an application process; skip it.
1796                                continue;
1797                            }
1798                            synchronized (mPidsSelfLocked) {
1799                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1800                                    // This is one of our own processes; skip it.
1801                                    continue;
1802                                }
1803                            }
1804                            nativeTotalPss += Debug.getPss(st.pid, null);
1805                        }
1806                    }
1807                    memInfo.readMemInfo();
1808                    synchronized (ActivityManagerService.this) {
1809                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1810                                + (SystemClock.uptimeMillis()-start) + "ms");
1811                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1812                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1813                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1814                    }
1815                }
1816
1817                int i = 0;
1818                int num = 0;
1819                long[] tmp = new long[1];
1820                do {
1821                    ProcessRecord proc;
1822                    int procState;
1823                    int pid;
1824                    synchronized (ActivityManagerService.this) {
1825                        if (i >= mPendingPssProcesses.size()) {
1826                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1827                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1828                            mPendingPssProcesses.clear();
1829                            return;
1830                        }
1831                        proc = mPendingPssProcesses.get(i);
1832                        procState = proc.pssProcState;
1833                        if (proc.thread != null && procState == proc.setProcState) {
1834                            pid = proc.pid;
1835                        } else {
1836                            proc = null;
1837                            pid = 0;
1838                        }
1839                        i++;
1840                    }
1841                    if (proc != null) {
1842                        long pss = Debug.getPss(pid, tmp);
1843                        synchronized (ActivityManagerService.this) {
1844                            if (proc.thread != null && proc.setProcState == procState
1845                                    && proc.pid == pid) {
1846                                num++;
1847                                proc.lastPssTime = SystemClock.uptimeMillis();
1848                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1849                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1850                                        + ": " + pss + " lastPss=" + proc.lastPss
1851                                        + " state=" + ProcessList.makeProcStateString(procState));
1852                                if (proc.initialIdlePss == 0) {
1853                                    proc.initialIdlePss = pss;
1854                                }
1855                                proc.lastPss = pss;
1856                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1857                                    proc.lastCachedPss = pss;
1858                                }
1859                            }
1860                        }
1861                    }
1862                } while (true);
1863            }
1864            }
1865        }
1866    };
1867
1868    public void setSystemProcess() {
1869        try {
1870            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1871            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1872            ServiceManager.addService("meminfo", new MemBinder(this));
1873            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1874            ServiceManager.addService("dbinfo", new DbBinder(this));
1875            if (MONITOR_CPU_USAGE) {
1876                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1877            }
1878            ServiceManager.addService("permission", new PermissionController(this));
1879
1880            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1881                    "android", STOCK_PM_FLAGS);
1882            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1883
1884            synchronized (this) {
1885                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1886                app.persistent = true;
1887                app.pid = MY_PID;
1888                app.maxAdj = ProcessList.SYSTEM_ADJ;
1889                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1890                mProcessNames.put(app.processName, app.uid, app);
1891                synchronized (mPidsSelfLocked) {
1892                    mPidsSelfLocked.put(app.pid, app);
1893                }
1894                updateLruProcessLocked(app, false, null);
1895                updateOomAdjLocked();
1896            }
1897        } catch (PackageManager.NameNotFoundException e) {
1898            throw new RuntimeException(
1899                    "Unable to find android system package", e);
1900        }
1901    }
1902
1903    public void setWindowManager(WindowManagerService wm) {
1904        mWindowManager = wm;
1905        mStackSupervisor.setWindowManager(wm);
1906    }
1907
1908    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1909        mUsageStatsService = usageStatsManager;
1910    }
1911
1912    public void startObservingNativeCrashes() {
1913        final NativeCrashListener ncl = new NativeCrashListener(this);
1914        ncl.start();
1915    }
1916
1917    public IAppOpsService getAppOpsService() {
1918        return mAppOpsService;
1919    }
1920
1921    static class MemBinder extends Binder {
1922        ActivityManagerService mActivityManagerService;
1923        MemBinder(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 meminfo from from pid="
1932                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1933                        + " without permission " + android.Manifest.permission.DUMP);
1934                return;
1935            }
1936
1937            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1938        }
1939    }
1940
1941    static class GraphicsBinder extends Binder {
1942        ActivityManagerService mActivityManagerService;
1943        GraphicsBinder(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 gfxinfo from from pid="
1952                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1953                        + " without permission " + android.Manifest.permission.DUMP);
1954                return;
1955            }
1956
1957            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1958        }
1959    }
1960
1961    static class DbBinder extends Binder {
1962        ActivityManagerService mActivityManagerService;
1963        DbBinder(ActivityManagerService activityManagerService) {
1964            mActivityManagerService = activityManagerService;
1965        }
1966
1967        @Override
1968        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1969            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1970                    != PackageManager.PERMISSION_GRANTED) {
1971                pw.println("Permission Denial: can't dump dbinfo from from pid="
1972                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1973                        + " without permission " + android.Manifest.permission.DUMP);
1974                return;
1975            }
1976
1977            mActivityManagerService.dumpDbInfo(fd, pw, args);
1978        }
1979    }
1980
1981    static class CpuBinder extends Binder {
1982        ActivityManagerService mActivityManagerService;
1983        CpuBinder(ActivityManagerService activityManagerService) {
1984            mActivityManagerService = activityManagerService;
1985        }
1986
1987        @Override
1988        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1989            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1990                    != PackageManager.PERMISSION_GRANTED) {
1991                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1992                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1993                        + " without permission " + android.Manifest.permission.DUMP);
1994                return;
1995            }
1996
1997            synchronized (mActivityManagerService.mProcessCpuTracker) {
1998                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1999                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2000                        SystemClock.uptimeMillis()));
2001            }
2002        }
2003    }
2004
2005    public static final class Lifecycle extends SystemService {
2006        private final ActivityManagerService mService;
2007
2008        public Lifecycle(Context context) {
2009            super(context);
2010            mService = new ActivityManagerService(context);
2011        }
2012
2013        @Override
2014        public void onStart() {
2015            mService.start();
2016        }
2017
2018        public ActivityManagerService getService() {
2019            return mService;
2020        }
2021    }
2022
2023    // Note: This method is invoked on the main thread but may need to attach various
2024    // handlers to other threads.  So take care to be explicit about the looper.
2025    public ActivityManagerService(Context systemContext) {
2026        mContext = systemContext;
2027        mFactoryTest = FactoryTest.getMode();
2028        mSystemThread = ActivityThread.currentActivityThread();
2029
2030        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2031
2032        mHandlerThread = new ServiceThread(TAG,
2033                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2034        mHandlerThread.start();
2035        mHandler = new MainHandler(mHandlerThread.getLooper());
2036
2037        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2038                "foreground", BROADCAST_FG_TIMEOUT, false);
2039        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2040                "background", BROADCAST_BG_TIMEOUT, true);
2041        mBroadcastQueues[0] = mFgBroadcastQueue;
2042        mBroadcastQueues[1] = mBgBroadcastQueue;
2043
2044        mServices = new ActiveServices(this);
2045        mProviderMap = new ProviderMap(this);
2046
2047        // TODO: Move creation of battery stats service outside of activity manager service.
2048        File dataDir = Environment.getDataDirectory();
2049        File systemDir = new File(dataDir, "system");
2050        systemDir.mkdirs();
2051        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2052        mBatteryStatsService.getActiveStatistics().readLocked();
2053        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2054        mOnBattery = DEBUG_POWER ? true
2055                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2056        mBatteryStatsService.getActiveStatistics().setCallback(this);
2057
2058        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2059
2060        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2061
2062        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2063
2064        // User 0 is the first and only user that runs at boot.
2065        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2066        mUserLru.add(Integer.valueOf(0));
2067        updateStartedUserArrayLocked();
2068
2069        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2070            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2071
2072        mConfiguration.setToDefaults();
2073        mConfiguration.setLocale(Locale.getDefault());
2074
2075        mConfigurationSeq = mConfiguration.seq = 1;
2076        mProcessCpuTracker.init();
2077
2078        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2079        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2080        mStackSupervisor = new ActivityStackSupervisor(this);
2081        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2082
2083        mProcessCpuThread = new Thread("CpuTracker") {
2084            @Override
2085            public void run() {
2086                while (true) {
2087                    try {
2088                        try {
2089                            synchronized(this) {
2090                                final long now = SystemClock.uptimeMillis();
2091                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2092                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2093                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2094                                //        + ", write delay=" + nextWriteDelay);
2095                                if (nextWriteDelay < nextCpuDelay) {
2096                                    nextCpuDelay = nextWriteDelay;
2097                                }
2098                                if (nextCpuDelay > 0) {
2099                                    mProcessCpuMutexFree.set(true);
2100                                    this.wait(nextCpuDelay);
2101                                }
2102                            }
2103                        } catch (InterruptedException e) {
2104                        }
2105                        updateCpuStatsNow();
2106                    } catch (Exception e) {
2107                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2108                    }
2109                }
2110            }
2111        };
2112
2113        Watchdog.getInstance().addMonitor(this);
2114        Watchdog.getInstance().addThread(mHandler);
2115    }
2116
2117    public void setSystemServiceManager(SystemServiceManager mgr) {
2118        mSystemServiceManager = mgr;
2119    }
2120
2121    public void setInstaller(Installer installer) {
2122        mInstaller = installer;
2123    }
2124
2125    private void start() {
2126        Process.removeAllProcessGroups();
2127        mProcessCpuThread.start();
2128
2129        mBatteryStatsService.publish(mContext);
2130        mAppOpsService.publish(mContext);
2131        Slog.d("AppOps", "AppOpsService published");
2132        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2133    }
2134
2135    public void initPowerManagement() {
2136        mStackSupervisor.initPowerManagement();
2137        mBatteryStatsService.initPowerManagement();
2138    }
2139
2140    @Override
2141    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2142            throws RemoteException {
2143        if (code == SYSPROPS_TRANSACTION) {
2144            // We need to tell all apps about the system property change.
2145            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2146            synchronized(this) {
2147                final int NP = mProcessNames.getMap().size();
2148                for (int ip=0; ip<NP; ip++) {
2149                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2150                    final int NA = apps.size();
2151                    for (int ia=0; ia<NA; ia++) {
2152                        ProcessRecord app = apps.valueAt(ia);
2153                        if (app.thread != null) {
2154                            procs.add(app.thread.asBinder());
2155                        }
2156                    }
2157                }
2158            }
2159
2160            int N = procs.size();
2161            for (int i=0; i<N; i++) {
2162                Parcel data2 = Parcel.obtain();
2163                try {
2164                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2165                } catch (RemoteException e) {
2166                }
2167                data2.recycle();
2168            }
2169        }
2170        try {
2171            return super.onTransact(code, data, reply, flags);
2172        } catch (RuntimeException e) {
2173            // The activity manager only throws security exceptions, so let's
2174            // log all others.
2175            if (!(e instanceof SecurityException)) {
2176                Slog.wtf(TAG, "Activity Manager Crash", e);
2177            }
2178            throw e;
2179        }
2180    }
2181
2182    void updateCpuStats() {
2183        final long now = SystemClock.uptimeMillis();
2184        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2185            return;
2186        }
2187        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2188            synchronized (mProcessCpuThread) {
2189                mProcessCpuThread.notify();
2190            }
2191        }
2192    }
2193
2194    void updateCpuStatsNow() {
2195        synchronized (mProcessCpuTracker) {
2196            mProcessCpuMutexFree.set(false);
2197            final long now = SystemClock.uptimeMillis();
2198            boolean haveNewCpuStats = false;
2199
2200            if (MONITOR_CPU_USAGE &&
2201                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2202                mLastCpuTime.set(now);
2203                haveNewCpuStats = true;
2204                mProcessCpuTracker.update();
2205                //Slog.i(TAG, mProcessCpu.printCurrentState());
2206                //Slog.i(TAG, "Total CPU usage: "
2207                //        + mProcessCpu.getTotalCpuPercent() + "%");
2208
2209                // Slog the cpu usage if the property is set.
2210                if ("true".equals(SystemProperties.get("events.cpu"))) {
2211                    int user = mProcessCpuTracker.getLastUserTime();
2212                    int system = mProcessCpuTracker.getLastSystemTime();
2213                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2214                    int irq = mProcessCpuTracker.getLastIrqTime();
2215                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2216                    int idle = mProcessCpuTracker.getLastIdleTime();
2217
2218                    int total = user + system + iowait + irq + softIrq + idle;
2219                    if (total == 0) total = 1;
2220
2221                    EventLog.writeEvent(EventLogTags.CPU,
2222                            ((user+system+iowait+irq+softIrq) * 100) / total,
2223                            (user * 100) / total,
2224                            (system * 100) / total,
2225                            (iowait * 100) / total,
2226                            (irq * 100) / total,
2227                            (softIrq * 100) / total);
2228                }
2229            }
2230
2231            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2232            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2233            synchronized(bstats) {
2234                synchronized(mPidsSelfLocked) {
2235                    if (haveNewCpuStats) {
2236                        if (mOnBattery) {
2237                            int perc = bstats.startAddingCpuLocked();
2238                            int totalUTime = 0;
2239                            int totalSTime = 0;
2240                            final int N = mProcessCpuTracker.countStats();
2241                            for (int i=0; i<N; i++) {
2242                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2243                                if (!st.working) {
2244                                    continue;
2245                                }
2246                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2247                                int otherUTime = (st.rel_utime*perc)/100;
2248                                int otherSTime = (st.rel_stime*perc)/100;
2249                                totalUTime += otherUTime;
2250                                totalSTime += otherSTime;
2251                                if (pr != null) {
2252                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2253                                    if (ps == null || !ps.isActive()) {
2254                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2255                                                pr.info.uid, pr.processName);
2256                                    }
2257                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2258                                            st.rel_stime-otherSTime);
2259                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2260                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2261                                } else {
2262                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2263                                    if (ps == null || !ps.isActive()) {
2264                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2265                                                bstats.mapUid(st.uid), st.name);
2266                                    }
2267                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2268                                            st.rel_stime-otherSTime);
2269                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2270                                }
2271                            }
2272                            bstats.finishAddingCpuLocked(perc, totalUTime,
2273                                    totalSTime, cpuSpeedTimes);
2274                        }
2275                    }
2276                }
2277
2278                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2279                    mLastWriteTime = now;
2280                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2281                }
2282            }
2283        }
2284    }
2285
2286    @Override
2287    public void batteryNeedsCpuUpdate() {
2288        updateCpuStatsNow();
2289    }
2290
2291    @Override
2292    public void batteryPowerChanged(boolean onBattery) {
2293        // When plugging in, update the CPU stats first before changing
2294        // the plug state.
2295        updateCpuStatsNow();
2296        synchronized (this) {
2297            synchronized(mPidsSelfLocked) {
2298                mOnBattery = DEBUG_POWER ? true : onBattery;
2299            }
2300        }
2301    }
2302
2303    /**
2304     * Initialize the application bind args. These are passed to each
2305     * process when the bindApplication() IPC is sent to the process. They're
2306     * lazily setup to make sure the services are running when they're asked for.
2307     */
2308    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2309        if (mAppBindArgs == null) {
2310            mAppBindArgs = new HashMap<>();
2311
2312            // Isolated processes won't get this optimization, so that we don't
2313            // violate the rules about which services they have access to.
2314            if (!isolated) {
2315                // Setup the application init args
2316                mAppBindArgs.put("package", ServiceManager.getService("package"));
2317                mAppBindArgs.put("window", ServiceManager.getService("window"));
2318                mAppBindArgs.put(Context.ALARM_SERVICE,
2319                        ServiceManager.getService(Context.ALARM_SERVICE));
2320            }
2321        }
2322        return mAppBindArgs;
2323    }
2324
2325    final void setFocusedActivityLocked(ActivityRecord r) {
2326        if (mFocusedActivity != r) {
2327            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2328            mFocusedActivity = r;
2329            if (r.task != null && r.task.voiceInteractor != null) {
2330                startRunningVoiceLocked();
2331            } else {
2332                finishRunningVoiceLocked();
2333            }
2334            mStackSupervisor.setFocusedStack(r);
2335            if (r != null) {
2336                mWindowManager.setFocusedApp(r.appToken, true);
2337            }
2338            applyUpdateLockStateLocked(r);
2339        }
2340    }
2341
2342    final void clearFocusedActivity(ActivityRecord r) {
2343        if (mFocusedActivity == r) {
2344            mFocusedActivity = null;
2345        }
2346    }
2347
2348    @Override
2349    public void setFocusedStack(int stackId) {
2350        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2351        synchronized (ActivityManagerService.this) {
2352            ActivityStack stack = mStackSupervisor.getStack(stackId);
2353            if (stack != null) {
2354                ActivityRecord r = stack.topRunningActivityLocked(null);
2355                if (r != null) {
2356                    setFocusedActivityLocked(r);
2357                }
2358            }
2359        }
2360    }
2361
2362    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2363    @Override
2364    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2365        synchronized (ActivityManagerService.this) {
2366            if (listener != null) {
2367                mTaskStackListeners.register(listener);
2368            }
2369        }
2370    }
2371
2372    @Override
2373    public void notifyActivityDrawn(IBinder token) {
2374        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2375        synchronized (this) {
2376            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2377            if (r != null) {
2378                r.task.stack.notifyActivityDrawnLocked(r);
2379            }
2380        }
2381    }
2382
2383    final void applyUpdateLockStateLocked(ActivityRecord r) {
2384        // Modifications to the UpdateLock state are done on our handler, outside
2385        // the activity manager's locks.  The new state is determined based on the
2386        // state *now* of the relevant activity record.  The object is passed to
2387        // the handler solely for logging detail, not to be consulted/modified.
2388        final boolean nextState = r != null && r.immersive;
2389        mHandler.sendMessage(
2390                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2391    }
2392
2393    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2394        Message msg = Message.obtain();
2395        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2396        msg.obj = r.task.askedCompatMode ? null : r;
2397        mHandler.sendMessage(msg);
2398    }
2399
2400    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2401            String what, Object obj, ProcessRecord srcApp) {
2402        app.lastActivityTime = now;
2403
2404        if (app.activities.size() > 0) {
2405            // Don't want to touch dependent processes that are hosting activities.
2406            return index;
2407        }
2408
2409        int lrui = mLruProcesses.lastIndexOf(app);
2410        if (lrui < 0) {
2411            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2412                    + what + " " + obj + " from " + srcApp);
2413            return index;
2414        }
2415
2416        if (lrui >= index) {
2417            // Don't want to cause this to move dependent processes *back* in the
2418            // list as if they were less frequently used.
2419            return index;
2420        }
2421
2422        if (lrui >= mLruProcessActivityStart) {
2423            // Don't want to touch dependent processes that are hosting activities.
2424            return index;
2425        }
2426
2427        mLruProcesses.remove(lrui);
2428        if (index > 0) {
2429            index--;
2430        }
2431        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2432                + " in LRU list: " + app);
2433        mLruProcesses.add(index, app);
2434        return index;
2435    }
2436
2437    final void removeLruProcessLocked(ProcessRecord app) {
2438        int lrui = mLruProcesses.lastIndexOf(app);
2439        if (lrui >= 0) {
2440            if (!app.killed) {
2441                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2442                Process.killProcessQuiet(app.pid);
2443                Process.killProcessGroup(app.info.uid, app.pid);
2444            }
2445            if (lrui <= mLruProcessActivityStart) {
2446                mLruProcessActivityStart--;
2447            }
2448            if (lrui <= mLruProcessServiceStart) {
2449                mLruProcessServiceStart--;
2450            }
2451            mLruProcesses.remove(lrui);
2452        }
2453    }
2454
2455    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2456            ProcessRecord client) {
2457        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2458                || app.treatLikeActivity;
2459        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2460        if (!activityChange && hasActivity) {
2461            // The process has activities, so we are only allowing activity-based adjustments
2462            // to move it.  It should be kept in the front of the list with other
2463            // processes that have activities, and we don't want those to change their
2464            // order except due to activity operations.
2465            return;
2466        }
2467
2468        mLruSeq++;
2469        final long now = SystemClock.uptimeMillis();
2470        app.lastActivityTime = now;
2471
2472        // First a quick reject: if the app is already at the position we will
2473        // put it, then there is nothing to do.
2474        if (hasActivity) {
2475            final int N = mLruProcesses.size();
2476            if (N > 0 && mLruProcesses.get(N-1) == app) {
2477                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2478                return;
2479            }
2480        } else {
2481            if (mLruProcessServiceStart > 0
2482                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2483                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2484                return;
2485            }
2486        }
2487
2488        int lrui = mLruProcesses.lastIndexOf(app);
2489
2490        if (app.persistent && lrui >= 0) {
2491            // We don't care about the position of persistent processes, as long as
2492            // they are in the list.
2493            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2494            return;
2495        }
2496
2497        /* In progress: compute new position first, so we can avoid doing work
2498           if the process is not actually going to move.  Not yet working.
2499        int addIndex;
2500        int nextIndex;
2501        boolean inActivity = false, inService = false;
2502        if (hasActivity) {
2503            // Process has activities, put it at the very tipsy-top.
2504            addIndex = mLruProcesses.size();
2505            nextIndex = mLruProcessServiceStart;
2506            inActivity = true;
2507        } else if (hasService) {
2508            // Process has services, put it at the top of the service list.
2509            addIndex = mLruProcessActivityStart;
2510            nextIndex = mLruProcessServiceStart;
2511            inActivity = true;
2512            inService = true;
2513        } else  {
2514            // Process not otherwise of interest, it goes to the top of the non-service area.
2515            addIndex = mLruProcessServiceStart;
2516            if (client != null) {
2517                int clientIndex = mLruProcesses.lastIndexOf(client);
2518                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2519                        + app);
2520                if (clientIndex >= 0 && addIndex > clientIndex) {
2521                    addIndex = clientIndex;
2522                }
2523            }
2524            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2525        }
2526
2527        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2528                + mLruProcessActivityStart + "): " + app);
2529        */
2530
2531        if (lrui >= 0) {
2532            if (lrui < mLruProcessActivityStart) {
2533                mLruProcessActivityStart--;
2534            }
2535            if (lrui < mLruProcessServiceStart) {
2536                mLruProcessServiceStart--;
2537            }
2538            /*
2539            if (addIndex > lrui) {
2540                addIndex--;
2541            }
2542            if (nextIndex > lrui) {
2543                nextIndex--;
2544            }
2545            */
2546            mLruProcesses.remove(lrui);
2547        }
2548
2549        /*
2550        mLruProcesses.add(addIndex, app);
2551        if (inActivity) {
2552            mLruProcessActivityStart++;
2553        }
2554        if (inService) {
2555            mLruProcessActivityStart++;
2556        }
2557        */
2558
2559        int nextIndex;
2560        if (hasActivity) {
2561            final int N = mLruProcesses.size();
2562            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2563                // Process doesn't have activities, but has clients with
2564                // activities...  move it up, but one below the top (the top
2565                // should always have a real activity).
2566                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2567                mLruProcesses.add(N-1, app);
2568                // To keep it from spamming the LRU list (by making a bunch of clients),
2569                // we will push down any other entries owned by the app.
2570                final int uid = app.info.uid;
2571                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2572                    ProcessRecord subProc = mLruProcesses.get(i);
2573                    if (subProc.info.uid == uid) {
2574                        // We want to push this one down the list.  If the process after
2575                        // it is for the same uid, however, don't do so, because we don't
2576                        // want them internally to be re-ordered.
2577                        if (mLruProcesses.get(i-1).info.uid != uid) {
2578                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2579                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2580                            ProcessRecord tmp = mLruProcesses.get(i);
2581                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2582                            mLruProcesses.set(i-1, tmp);
2583                            i--;
2584                        }
2585                    } else {
2586                        // A gap, we can stop here.
2587                        break;
2588                    }
2589                }
2590            } else {
2591                // Process has activities, put it at the very tipsy-top.
2592                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2593                mLruProcesses.add(app);
2594            }
2595            nextIndex = mLruProcessServiceStart;
2596        } else if (hasService) {
2597            // Process has services, put it at the top of the service list.
2598            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2599            mLruProcesses.add(mLruProcessActivityStart, app);
2600            nextIndex = mLruProcessServiceStart;
2601            mLruProcessActivityStart++;
2602        } else  {
2603            // Process not otherwise of interest, it goes to the top of the non-service area.
2604            int index = mLruProcessServiceStart;
2605            if (client != null) {
2606                // If there is a client, don't allow the process to be moved up higher
2607                // in the list than that client.
2608                int clientIndex = mLruProcesses.lastIndexOf(client);
2609                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2610                        + " when updating " + app);
2611                if (clientIndex <= lrui) {
2612                    // Don't allow the client index restriction to push it down farther in the
2613                    // list than it already is.
2614                    clientIndex = lrui;
2615                }
2616                if (clientIndex >= 0 && index > clientIndex) {
2617                    index = clientIndex;
2618                }
2619            }
2620            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2621            mLruProcesses.add(index, app);
2622            nextIndex = index-1;
2623            mLruProcessActivityStart++;
2624            mLruProcessServiceStart++;
2625        }
2626
2627        // If the app is currently using a content provider or service,
2628        // bump those processes as well.
2629        for (int j=app.connections.size()-1; j>=0; j--) {
2630            ConnectionRecord cr = app.connections.valueAt(j);
2631            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2632                    && cr.binding.service.app != null
2633                    && cr.binding.service.app.lruSeq != mLruSeq
2634                    && !cr.binding.service.app.persistent) {
2635                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2636                        "service connection", cr, app);
2637            }
2638        }
2639        for (int j=app.conProviders.size()-1; j>=0; j--) {
2640            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2641            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2642                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2643                        "provider reference", cpr, app);
2644            }
2645        }
2646    }
2647
2648    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2649        if (uid == Process.SYSTEM_UID) {
2650            // The system gets to run in any process.  If there are multiple
2651            // processes with the same uid, just pick the first (this
2652            // should never happen).
2653            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2654            if (procs == null) return null;
2655            final int N = procs.size();
2656            for (int i = 0; i < N; i++) {
2657                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2658            }
2659        }
2660        ProcessRecord proc = mProcessNames.get(processName, uid);
2661        if (false && proc != null && !keepIfLarge
2662                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2663                && proc.lastCachedPss >= 4000) {
2664            // Turn this condition on to cause killing to happen regularly, for testing.
2665            if (proc.baseProcessTracker != null) {
2666                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2667            }
2668            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2669        } else if (proc != null && !keepIfLarge
2670                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2671                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2672            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2673            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2674                if (proc.baseProcessTracker != null) {
2675                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2676                }
2677                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2678            }
2679        }
2680        return proc;
2681    }
2682
2683    void ensurePackageDexOpt(String packageName) {
2684        IPackageManager pm = AppGlobals.getPackageManager();
2685        try {
2686            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2687                mDidDexOpt = true;
2688            }
2689        } catch (RemoteException e) {
2690        }
2691    }
2692
2693    boolean isNextTransitionForward() {
2694        int transit = mWindowManager.getPendingAppTransition();
2695        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2696                || transit == AppTransition.TRANSIT_TASK_OPEN
2697                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2698    }
2699
2700    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2701            String processName, String abiOverride, int uid, Runnable crashHandler) {
2702        synchronized(this) {
2703            ApplicationInfo info = new ApplicationInfo();
2704            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2705            // For isolated processes, the former contains the parent's uid and the latter the
2706            // actual uid of the isolated process.
2707            // In the special case introduced by this method (which is, starting an isolated
2708            // process directly from the SystemServer without an actual parent app process) the
2709            // closest thing to a parent's uid is SYSTEM_UID.
2710            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2711            // the |isolated| logic in the ProcessRecord constructor.
2712            info.uid = Process.SYSTEM_UID;
2713            info.processName = processName;
2714            info.className = entryPoint;
2715            info.packageName = "android";
2716            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2717                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2718                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2719                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2720                    crashHandler);
2721            return proc != null ? proc.pid : 0;
2722        }
2723    }
2724
2725    final ProcessRecord startProcessLocked(String processName,
2726            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2727            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2728            boolean isolated, boolean keepIfLarge) {
2729        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2730                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2731                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2732                null /* crashHandler */);
2733    }
2734
2735    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2736            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2737            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2738            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2739        long startTime = SystemClock.elapsedRealtime();
2740        ProcessRecord app;
2741        if (!isolated) {
2742            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2743            checkTime(startTime, "startProcess: after getProcessRecord");
2744        } else {
2745            // If this is an isolated process, it can't re-use an existing process.
2746            app = null;
2747        }
2748        // We don't have to do anything more if:
2749        // (1) There is an existing application record; and
2750        // (2) The caller doesn't think it is dead, OR there is no thread
2751        //     object attached to it so we know it couldn't have crashed; and
2752        // (3) There is a pid assigned to it, so it is either starting or
2753        //     already running.
2754        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2755                + " app=" + app + " knownToBeDead=" + knownToBeDead
2756                + " thread=" + (app != null ? app.thread : null)
2757                + " pid=" + (app != null ? app.pid : -1));
2758        if (app != null && app.pid > 0) {
2759            if (!knownToBeDead || app.thread == null) {
2760                // We already have the app running, or are waiting for it to
2761                // come up (we have a pid but not yet its thread), so keep it.
2762                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2763                // If this is a new package in the process, add the package to the list
2764                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2765                checkTime(startTime, "startProcess: done, added package to proc");
2766                return app;
2767            }
2768
2769            // An application record is attached to a previous process,
2770            // clean it up now.
2771            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2772            checkTime(startTime, "startProcess: bad proc running, killing");
2773            Process.killProcessGroup(app.info.uid, app.pid);
2774            handleAppDiedLocked(app, true, true);
2775            checkTime(startTime, "startProcess: done killing old proc");
2776        }
2777
2778        String hostingNameStr = hostingName != null
2779                ? hostingName.flattenToShortString() : null;
2780
2781        if (!isolated) {
2782            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2783                // If we are in the background, then check to see if this process
2784                // is bad.  If so, we will just silently fail.
2785                if (mBadProcesses.get(info.processName, info.uid) != null) {
2786                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2787                            + "/" + info.processName);
2788                    return null;
2789                }
2790            } else {
2791                // When the user is explicitly starting a process, then clear its
2792                // crash count so that we won't make it bad until they see at
2793                // least one crash dialog again, and make the process good again
2794                // if it had been bad.
2795                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2796                        + "/" + info.processName);
2797                mProcessCrashTimes.remove(info.processName, info.uid);
2798                if (mBadProcesses.get(info.processName, info.uid) != null) {
2799                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2800                            UserHandle.getUserId(info.uid), info.uid,
2801                            info.processName);
2802                    mBadProcesses.remove(info.processName, info.uid);
2803                    if (app != null) {
2804                        app.bad = false;
2805                    }
2806                }
2807            }
2808        }
2809
2810        if (app == null) {
2811            checkTime(startTime, "startProcess: creating new process record");
2812            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2813            if (app == null) {
2814                Slog.w(TAG, "Failed making new process record for "
2815                        + processName + "/" + info.uid + " isolated=" + isolated);
2816                return null;
2817            }
2818            app.crashHandler = crashHandler;
2819            mProcessNames.put(processName, app.uid, app);
2820            if (isolated) {
2821                mIsolatedProcesses.put(app.uid, app);
2822            }
2823            checkTime(startTime, "startProcess: done creating new process record");
2824        } else {
2825            // If this is a new package in the process, add the package to the list
2826            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2827            checkTime(startTime, "startProcess: added package to existing proc");
2828        }
2829
2830        // If the system is not ready yet, then hold off on starting this
2831        // process until it is.
2832        if (!mProcessesReady
2833                && !isAllowedWhileBooting(info)
2834                && !allowWhileBooting) {
2835            if (!mProcessesOnHold.contains(app)) {
2836                mProcessesOnHold.add(app);
2837            }
2838            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2839            checkTime(startTime, "startProcess: returning with proc on hold");
2840            return app;
2841        }
2842
2843        checkTime(startTime, "startProcess: stepping in to startProcess");
2844        startProcessLocked(
2845                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2846        checkTime(startTime, "startProcess: done starting proc!");
2847        return (app.pid != 0) ? app : null;
2848    }
2849
2850    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2851        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2852    }
2853
2854    private final void startProcessLocked(ProcessRecord app,
2855            String hostingType, String hostingNameStr) {
2856        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2857                null /* entryPoint */, null /* entryPointArgs */);
2858    }
2859
2860    private final void startProcessLocked(ProcessRecord app, String hostingType,
2861            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2862        long startTime = SystemClock.elapsedRealtime();
2863        if (app.pid > 0 && app.pid != MY_PID) {
2864            checkTime(startTime, "startProcess: removing from pids map");
2865            synchronized (mPidsSelfLocked) {
2866                mPidsSelfLocked.remove(app.pid);
2867                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2868            }
2869            checkTime(startTime, "startProcess: done removing from pids map");
2870            app.setPid(0);
2871        }
2872
2873        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2874                "startProcessLocked removing on hold: " + app);
2875        mProcessesOnHold.remove(app);
2876
2877        checkTime(startTime, "startProcess: starting to update cpu stats");
2878        updateCpuStats();
2879        checkTime(startTime, "startProcess: done updating cpu stats");
2880
2881        try {
2882            int uid = app.uid;
2883
2884            int[] gids = null;
2885            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2886            if (!app.isolated) {
2887                int[] permGids = null;
2888                try {
2889                    checkTime(startTime, "startProcess: getting gids from package manager");
2890                    final PackageManager pm = mContext.getPackageManager();
2891                    permGids = pm.getPackageGids(app.info.packageName);
2892
2893                    if (Environment.isExternalStorageEmulated()) {
2894                        checkTime(startTime, "startProcess: checking external storage perm");
2895                        if (pm.checkPermission(
2896                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2897                                app.info.packageName) == PERMISSION_GRANTED) {
2898                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2899                        } else {
2900                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2901                        }
2902                    }
2903                } catch (PackageManager.NameNotFoundException e) {
2904                    Slog.w(TAG, "Unable to retrieve gids", e);
2905                }
2906
2907                /*
2908                 * Add shared application and profile GIDs so applications can share some
2909                 * resources like shared libraries and access user-wide resources
2910                 */
2911                if (permGids == null) {
2912                    gids = new int[2];
2913                } else {
2914                    gids = new int[permGids.length + 2];
2915                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2916                }
2917                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2918                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2919            }
2920            checkTime(startTime, "startProcess: building args");
2921            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2922                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2923                        && mTopComponent != null
2924                        && app.processName.equals(mTopComponent.getPackageName())) {
2925                    uid = 0;
2926                }
2927                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2928                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2929                    uid = 0;
2930                }
2931            }
2932            int debugFlags = 0;
2933            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2934                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2935                // Also turn on CheckJNI for debuggable apps. It's quite
2936                // awkward to turn on otherwise.
2937                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2938            }
2939            // Run the app in safe mode if its manifest requests so or the
2940            // system is booted in safe mode.
2941            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2942                mSafeMode == true) {
2943                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2944            }
2945            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2946                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2947            }
2948            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2949                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2950            }
2951            if ("1".equals(SystemProperties.get("debug.assert"))) {
2952                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2953            }
2954
2955            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2956            if (requiredAbi == null) {
2957                requiredAbi = Build.SUPPORTED_ABIS[0];
2958            }
2959
2960            String instructionSet = null;
2961            if (app.info.primaryCpuAbi != null) {
2962                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2963            }
2964
2965            // Start the process.  It will either succeed and return a result containing
2966            // the PID of the new process, or else throw a RuntimeException.
2967            boolean isActivityProcess = (entryPoint == null);
2968            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2969            checkTime(startTime, "startProcess: asking zygote to start proc");
2970            Process.ProcessStartResult startResult = Process.start(entryPoint,
2971                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2972                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2973                    app.info.dataDir, entryPointArgs);
2974            checkTime(startTime, "startProcess: returned from zygote!");
2975
2976            if (app.isolated) {
2977                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2978            }
2979            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2980            checkTime(startTime, "startProcess: done updating battery stats");
2981
2982            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2983                    UserHandle.getUserId(uid), startResult.pid, uid,
2984                    app.processName, hostingType,
2985                    hostingNameStr != null ? hostingNameStr : "");
2986
2987            if (app.persistent) {
2988                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2989            }
2990
2991            checkTime(startTime, "startProcess: building log message");
2992            StringBuilder buf = mStringBuilder;
2993            buf.setLength(0);
2994            buf.append("Start proc ");
2995            buf.append(app.processName);
2996            if (!isActivityProcess) {
2997                buf.append(" [");
2998                buf.append(entryPoint);
2999                buf.append("]");
3000            }
3001            buf.append(" for ");
3002            buf.append(hostingType);
3003            if (hostingNameStr != null) {
3004                buf.append(" ");
3005                buf.append(hostingNameStr);
3006            }
3007            buf.append(": pid=");
3008            buf.append(startResult.pid);
3009            buf.append(" uid=");
3010            buf.append(uid);
3011            buf.append(" gids={");
3012            if (gids != null) {
3013                for (int gi=0; gi<gids.length; gi++) {
3014                    if (gi != 0) buf.append(", ");
3015                    buf.append(gids[gi]);
3016
3017                }
3018            }
3019            buf.append("}");
3020            if (requiredAbi != null) {
3021                buf.append(" abi=");
3022                buf.append(requiredAbi);
3023            }
3024            Slog.i(TAG, buf.toString());
3025            app.setPid(startResult.pid);
3026            app.usingWrapper = startResult.usingWrapper;
3027            app.removed = false;
3028            app.killed = false;
3029            app.killedByAm = false;
3030            checkTime(startTime, "startProcess: starting to update pids map");
3031            synchronized (mPidsSelfLocked) {
3032                this.mPidsSelfLocked.put(startResult.pid, app);
3033                if (isActivityProcess) {
3034                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3035                    msg.obj = app;
3036                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3037                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3038                }
3039            }
3040            checkTime(startTime, "startProcess: done updating pids map");
3041        } catch (RuntimeException e) {
3042            // XXX do better error recovery.
3043            app.setPid(0);
3044            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3045            if (app.isolated) {
3046                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3047            }
3048            Slog.e(TAG, "Failure starting process " + app.processName, e);
3049        }
3050    }
3051
3052    void updateUsageStats(ActivityRecord component, boolean resumed) {
3053        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3054        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3055        if (resumed) {
3056            if (mUsageStatsService != null) {
3057                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3058                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3059            }
3060            synchronized (stats) {
3061                stats.noteActivityResumedLocked(component.app.uid);
3062            }
3063        } else {
3064            if (mUsageStatsService != null) {
3065                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3066                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3067            }
3068            synchronized (stats) {
3069                stats.noteActivityPausedLocked(component.app.uid);
3070            }
3071        }
3072    }
3073
3074    Intent getHomeIntent() {
3075        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3076        intent.setComponent(mTopComponent);
3077        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3078            intent.addCategory(Intent.CATEGORY_HOME);
3079        }
3080        return intent;
3081    }
3082
3083    boolean startHomeActivityLocked(int userId) {
3084        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3085                && mTopAction == null) {
3086            // We are running in factory test mode, but unable to find
3087            // the factory test app, so just sit around displaying the
3088            // error message and don't try to start anything.
3089            return false;
3090        }
3091        Intent intent = getHomeIntent();
3092        ActivityInfo aInfo =
3093            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3094        if (aInfo != null) {
3095            intent.setComponent(new ComponentName(
3096                    aInfo.applicationInfo.packageName, aInfo.name));
3097            // Don't do this if the home app is currently being
3098            // instrumented.
3099            aInfo = new ActivityInfo(aInfo);
3100            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3101            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3102                    aInfo.applicationInfo.uid, true);
3103            if (app == null || app.instrumentationClass == null) {
3104                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3105                mStackSupervisor.startHomeActivity(intent, aInfo);
3106            }
3107        }
3108
3109        return true;
3110    }
3111
3112    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3113        ActivityInfo ai = null;
3114        ComponentName comp = intent.getComponent();
3115        try {
3116            if (comp != null) {
3117                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3118            } else {
3119                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3120                        intent,
3121                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3122                            flags, userId);
3123
3124                if (info != null) {
3125                    ai = info.activityInfo;
3126                }
3127            }
3128        } catch (RemoteException e) {
3129            // ignore
3130        }
3131
3132        return ai;
3133    }
3134
3135    /**
3136     * Starts the "new version setup screen" if appropriate.
3137     */
3138    void startSetupActivityLocked() {
3139        // Only do this once per boot.
3140        if (mCheckedForSetup) {
3141            return;
3142        }
3143
3144        // We will show this screen if the current one is a different
3145        // version than the last one shown, and we are not running in
3146        // low-level factory test mode.
3147        final ContentResolver resolver = mContext.getContentResolver();
3148        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3149                Settings.Global.getInt(resolver,
3150                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3151            mCheckedForSetup = true;
3152
3153            // See if we should be showing the platform update setup UI.
3154            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3155            List<ResolveInfo> ris = mContext.getPackageManager()
3156                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3157
3158            // We don't allow third party apps to replace this.
3159            ResolveInfo ri = null;
3160            for (int i=0; ris != null && i<ris.size(); i++) {
3161                if ((ris.get(i).activityInfo.applicationInfo.flags
3162                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3163                    ri = ris.get(i);
3164                    break;
3165                }
3166            }
3167
3168            if (ri != null) {
3169                String vers = ri.activityInfo.metaData != null
3170                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3171                        : null;
3172                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3173                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3174                            Intent.METADATA_SETUP_VERSION);
3175                }
3176                String lastVers = Settings.Secure.getString(
3177                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3178                if (vers != null && !vers.equals(lastVers)) {
3179                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3180                    intent.setComponent(new ComponentName(
3181                            ri.activityInfo.packageName, ri.activityInfo.name));
3182                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3183                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3184                            null);
3185                }
3186            }
3187        }
3188    }
3189
3190    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3191        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3192    }
3193
3194    void enforceNotIsolatedCaller(String caller) {
3195        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3196            throw new SecurityException("Isolated process not allowed to call " + caller);
3197        }
3198    }
3199
3200    void enforceShellRestriction(String restriction, int userHandle) {
3201        if (Binder.getCallingUid() == Process.SHELL_UID) {
3202            if (userHandle < 0
3203                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3204                throw new SecurityException("Shell does not have permission to access user "
3205                        + userHandle);
3206            }
3207        }
3208    }
3209
3210    @Override
3211    public int getFrontActivityScreenCompatMode() {
3212        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3213        synchronized (this) {
3214            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3215        }
3216    }
3217
3218    @Override
3219    public void setFrontActivityScreenCompatMode(int mode) {
3220        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3221                "setFrontActivityScreenCompatMode");
3222        synchronized (this) {
3223            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3224        }
3225    }
3226
3227    @Override
3228    public int getPackageScreenCompatMode(String packageName) {
3229        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3230        synchronized (this) {
3231            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3232        }
3233    }
3234
3235    @Override
3236    public void setPackageScreenCompatMode(String packageName, int mode) {
3237        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3238                "setPackageScreenCompatMode");
3239        synchronized (this) {
3240            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3241        }
3242    }
3243
3244    @Override
3245    public boolean getPackageAskScreenCompat(String packageName) {
3246        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3247        synchronized (this) {
3248            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3249        }
3250    }
3251
3252    @Override
3253    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3254        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3255                "setPackageAskScreenCompat");
3256        synchronized (this) {
3257            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3258        }
3259    }
3260
3261    private void dispatchProcessesChanged() {
3262        int N;
3263        synchronized (this) {
3264            N = mPendingProcessChanges.size();
3265            if (mActiveProcessChanges.length < N) {
3266                mActiveProcessChanges = new ProcessChangeItem[N];
3267            }
3268            mPendingProcessChanges.toArray(mActiveProcessChanges);
3269            mAvailProcessChanges.addAll(mPendingProcessChanges);
3270            mPendingProcessChanges.clear();
3271            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3272        }
3273
3274        int i = mProcessObservers.beginBroadcast();
3275        while (i > 0) {
3276            i--;
3277            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3278            if (observer != null) {
3279                try {
3280                    for (int j=0; j<N; j++) {
3281                        ProcessChangeItem item = mActiveProcessChanges[j];
3282                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3283                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3284                                    + item.pid + " uid=" + item.uid + ": "
3285                                    + item.foregroundActivities);
3286                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3287                                    item.foregroundActivities);
3288                        }
3289                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3290                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3291                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3292                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3293                        }
3294                    }
3295                } catch (RemoteException e) {
3296                }
3297            }
3298        }
3299        mProcessObservers.finishBroadcast();
3300    }
3301
3302    private void dispatchProcessDied(int pid, int uid) {
3303        int i = mProcessObservers.beginBroadcast();
3304        while (i > 0) {
3305            i--;
3306            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3307            if (observer != null) {
3308                try {
3309                    observer.onProcessDied(pid, uid);
3310                } catch (RemoteException e) {
3311                }
3312            }
3313        }
3314        mProcessObservers.finishBroadcast();
3315    }
3316
3317    @Override
3318    public final int startActivity(IApplicationThread caller, String callingPackage,
3319            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3320            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3321        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3322            resultWho, requestCode, startFlags, profilerInfo, options,
3323            UserHandle.getCallingUserId());
3324    }
3325
3326    @Override
3327    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3328            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3329            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3330        enforceNotIsolatedCaller("startActivity");
3331        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3332                false, ALLOW_FULL_ONLY, "startActivity", null);
3333        // TODO: Switch to user app stacks here.
3334        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3335                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3336                profilerInfo, null, null, options, userId, null, null);
3337    }
3338
3339    @Override
3340    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3341            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3342            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3343
3344        // This is very dangerous -- it allows you to perform a start activity (including
3345        // permission grants) as any app that may launch one of your own activities.  So
3346        // we will only allow this to be done from activities that are part of the core framework,
3347        // and then only when they are running as the system.
3348        final ActivityRecord sourceRecord;
3349        final int targetUid;
3350        final String targetPackage;
3351        synchronized (this) {
3352            if (resultTo == null) {
3353                throw new SecurityException("Must be called from an activity");
3354            }
3355            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3356            if (sourceRecord == null) {
3357                throw new SecurityException("Called with bad activity token: " + resultTo);
3358            }
3359            if (!sourceRecord.info.packageName.equals("android")) {
3360                throw new SecurityException(
3361                        "Must be called from an activity that is declared in the android package");
3362            }
3363            if (sourceRecord.app == null) {
3364                throw new SecurityException("Called without a process attached to activity");
3365            }
3366            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3367                // This is still okay, as long as this activity is running under the
3368                // uid of the original calling activity.
3369                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3370                    throw new SecurityException(
3371                            "Calling activity in uid " + sourceRecord.app.uid
3372                                    + " must be system uid or original calling uid "
3373                                    + sourceRecord.launchedFromUid);
3374                }
3375            }
3376            targetUid = sourceRecord.launchedFromUid;
3377            targetPackage = sourceRecord.launchedFromPackage;
3378        }
3379
3380        if (userId == UserHandle.USER_NULL) {
3381            userId = UserHandle.getUserId(sourceRecord.app.uid);
3382        }
3383
3384        // TODO: Switch to user app stacks here.
3385        try {
3386            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3387                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3388                    null, null, options, userId, null, null);
3389            return ret;
3390        } catch (SecurityException e) {
3391            // XXX need to figure out how to propagate to original app.
3392            // A SecurityException here is generally actually a fault of the original
3393            // calling activity (such as a fairly granting permissions), so propagate it
3394            // back to them.
3395            /*
3396            StringBuilder msg = new StringBuilder();
3397            msg.append("While launching");
3398            msg.append(intent.toString());
3399            msg.append(": ");
3400            msg.append(e.getMessage());
3401            */
3402            throw e;
3403        }
3404    }
3405
3406    @Override
3407    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3408            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3409            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3410        enforceNotIsolatedCaller("startActivityAndWait");
3411        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3412                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3413        WaitResult res = new WaitResult();
3414        // TODO: Switch to user app stacks here.
3415        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3416                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3417                options, userId, null, null);
3418        return res;
3419    }
3420
3421    @Override
3422    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3423            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3424            int startFlags, Configuration config, Bundle options, int userId) {
3425        enforceNotIsolatedCaller("startActivityWithConfig");
3426        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3427                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3428        // TODO: Switch to user app stacks here.
3429        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3430                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3431                null, null, config, options, userId, null, null);
3432        return ret;
3433    }
3434
3435    @Override
3436    public int startActivityIntentSender(IApplicationThread caller,
3437            IntentSender intent, Intent fillInIntent, String resolvedType,
3438            IBinder resultTo, String resultWho, int requestCode,
3439            int flagsMask, int flagsValues, Bundle options) {
3440        enforceNotIsolatedCaller("startActivityIntentSender");
3441        // Refuse possible leaked file descriptors
3442        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3443            throw new IllegalArgumentException("File descriptors passed in Intent");
3444        }
3445
3446        IIntentSender sender = intent.getTarget();
3447        if (!(sender instanceof PendingIntentRecord)) {
3448            throw new IllegalArgumentException("Bad PendingIntent object");
3449        }
3450
3451        PendingIntentRecord pir = (PendingIntentRecord)sender;
3452
3453        synchronized (this) {
3454            // If this is coming from the currently resumed activity, it is
3455            // effectively saying that app switches are allowed at this point.
3456            final ActivityStack stack = getFocusedStack();
3457            if (stack.mResumedActivity != null &&
3458                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3459                mAppSwitchesAllowedTime = 0;
3460            }
3461        }
3462        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3463                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3464        return ret;
3465    }
3466
3467    @Override
3468    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3469            Intent intent, String resolvedType, IVoiceInteractionSession session,
3470            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3471            Bundle options, int userId) {
3472        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3473                != PackageManager.PERMISSION_GRANTED) {
3474            String msg = "Permission Denial: startVoiceActivity() from pid="
3475                    + Binder.getCallingPid()
3476                    + ", uid=" + Binder.getCallingUid()
3477                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3478            Slog.w(TAG, msg);
3479            throw new SecurityException(msg);
3480        }
3481        if (session == null || interactor == null) {
3482            throw new NullPointerException("null session or interactor");
3483        }
3484        userId = handleIncomingUser(callingPid, callingUid, userId,
3485                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3486        // TODO: Switch to user app stacks here.
3487        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3488                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3489                null, options, userId, null, null);
3490    }
3491
3492    @Override
3493    public boolean startNextMatchingActivity(IBinder callingActivity,
3494            Intent intent, Bundle options) {
3495        // Refuse possible leaked file descriptors
3496        if (intent != null && intent.hasFileDescriptors() == true) {
3497            throw new IllegalArgumentException("File descriptors passed in Intent");
3498        }
3499
3500        synchronized (this) {
3501            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3502            if (r == null) {
3503                ActivityOptions.abort(options);
3504                return false;
3505            }
3506            if (r.app == null || r.app.thread == null) {
3507                // The caller is not running...  d'oh!
3508                ActivityOptions.abort(options);
3509                return false;
3510            }
3511            intent = new Intent(intent);
3512            // The caller is not allowed to change the data.
3513            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3514            // And we are resetting to find the next component...
3515            intent.setComponent(null);
3516
3517            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3518
3519            ActivityInfo aInfo = null;
3520            try {
3521                List<ResolveInfo> resolves =
3522                    AppGlobals.getPackageManager().queryIntentActivities(
3523                            intent, r.resolvedType,
3524                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3525                            UserHandle.getCallingUserId());
3526
3527                // Look for the original activity in the list...
3528                final int N = resolves != null ? resolves.size() : 0;
3529                for (int i=0; i<N; i++) {
3530                    ResolveInfo rInfo = resolves.get(i);
3531                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3532                            && rInfo.activityInfo.name.equals(r.info.name)) {
3533                        // We found the current one...  the next matching is
3534                        // after it.
3535                        i++;
3536                        if (i<N) {
3537                            aInfo = resolves.get(i).activityInfo;
3538                        }
3539                        if (debug) {
3540                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3541                                    + "/" + r.info.name);
3542                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3543                                    + "/" + aInfo.name);
3544                        }
3545                        break;
3546                    }
3547                }
3548            } catch (RemoteException e) {
3549            }
3550
3551            if (aInfo == null) {
3552                // Nobody who is next!
3553                ActivityOptions.abort(options);
3554                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3555                return false;
3556            }
3557
3558            intent.setComponent(new ComponentName(
3559                    aInfo.applicationInfo.packageName, aInfo.name));
3560            intent.setFlags(intent.getFlags()&~(
3561                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3562                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3563                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3564                    Intent.FLAG_ACTIVITY_NEW_TASK));
3565
3566            // Okay now we need to start the new activity, replacing the
3567            // currently running activity.  This is a little tricky because
3568            // we want to start the new one as if the current one is finished,
3569            // but not finish the current one first so that there is no flicker.
3570            // And thus...
3571            final boolean wasFinishing = r.finishing;
3572            r.finishing = true;
3573
3574            // Propagate reply information over to the new activity.
3575            final ActivityRecord resultTo = r.resultTo;
3576            final String resultWho = r.resultWho;
3577            final int requestCode = r.requestCode;
3578            r.resultTo = null;
3579            if (resultTo != null) {
3580                resultTo.removeResultsLocked(r, resultWho, requestCode);
3581            }
3582
3583            final long origId = Binder.clearCallingIdentity();
3584            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3585                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3586                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3587                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3588            Binder.restoreCallingIdentity(origId);
3589
3590            r.finishing = wasFinishing;
3591            if (res != ActivityManager.START_SUCCESS) {
3592                return false;
3593            }
3594            return true;
3595        }
3596    }
3597
3598    @Override
3599    public final int startActivityFromRecents(int taskId, Bundle options) {
3600        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3601            String msg = "Permission Denial: startActivityFromRecents called without " +
3602                    START_TASKS_FROM_RECENTS;
3603            Slog.w(TAG, msg);
3604            throw new SecurityException(msg);
3605        }
3606        return startActivityFromRecentsInner(taskId, options);
3607    }
3608
3609    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3610        final TaskRecord task;
3611        final int callingUid;
3612        final String callingPackage;
3613        final Intent intent;
3614        final int userId;
3615        synchronized (this) {
3616            task = recentTaskForIdLocked(taskId);
3617            if (task == null) {
3618                throw new IllegalArgumentException("Task " + taskId + " not found.");
3619            }
3620            callingUid = task.mCallingUid;
3621            callingPackage = task.mCallingPackage;
3622            intent = task.intent;
3623            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3624            userId = task.userId;
3625        }
3626        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3627                options, userId, null, task);
3628    }
3629
3630    final int startActivityInPackage(int uid, String callingPackage,
3631            Intent intent, String resolvedType, IBinder resultTo,
3632            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3633            IActivityContainer container, TaskRecord inTask) {
3634
3635        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3636                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3637
3638        // TODO: Switch to user app stacks here.
3639        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3640                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3641                null, null, null, options, userId, container, inTask);
3642        return ret;
3643    }
3644
3645    @Override
3646    public final int startActivities(IApplicationThread caller, String callingPackage,
3647            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3648            int userId) {
3649        enforceNotIsolatedCaller("startActivities");
3650        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3651                false, ALLOW_FULL_ONLY, "startActivity", null);
3652        // TODO: Switch to user app stacks here.
3653        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3654                resolvedTypes, resultTo, options, userId);
3655        return ret;
3656    }
3657
3658    final int startActivitiesInPackage(int uid, String callingPackage,
3659            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3660            Bundle options, int userId) {
3661
3662        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3663                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3664        // TODO: Switch to user app stacks here.
3665        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3666                resultTo, options, userId);
3667        return ret;
3668    }
3669
3670    //explicitly remove thd old information in mRecentTasks when removing existing user.
3671    private void removeRecentTasksForUserLocked(int userId) {
3672        if(userId <= 0) {
3673            Slog.i(TAG, "Can't remove recent task on user " + userId);
3674            return;
3675        }
3676
3677        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3678            TaskRecord tr = mRecentTasks.get(i);
3679            if (tr.userId == userId) {
3680                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3681                        + " when finishing user" + userId);
3682                mRecentTasks.remove(i);
3683                tr.removedFromRecents();
3684            }
3685        }
3686
3687        // Remove tasks from persistent storage.
3688        notifyTaskPersisterLocked(null, true);
3689    }
3690
3691    // Sort by taskId
3692    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3693        @Override
3694        public int compare(TaskRecord lhs, TaskRecord rhs) {
3695            return rhs.taskId - lhs.taskId;
3696        }
3697    };
3698
3699    // Extract the affiliates of the chain containing mRecentTasks[start].
3700    private int processNextAffiliateChainLocked(int start) {
3701        final TaskRecord startTask = mRecentTasks.get(start);
3702        final int affiliateId = startTask.mAffiliatedTaskId;
3703
3704        // Quick identification of isolated tasks. I.e. those not launched behind.
3705        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3706                startTask.mNextAffiliate == null) {
3707            // There is still a slim chance that there are other tasks that point to this task
3708            // and that the chain is so messed up that this task no longer points to them but
3709            // the gain of this optimization outweighs the risk.
3710            startTask.inRecents = true;
3711            return start + 1;
3712        }
3713
3714        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3715        mTmpRecents.clear();
3716        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3717            final TaskRecord task = mRecentTasks.get(i);
3718            if (task.mAffiliatedTaskId == affiliateId) {
3719                mRecentTasks.remove(i);
3720                mTmpRecents.add(task);
3721            }
3722        }
3723
3724        // Sort them all by taskId. That is the order they were create in and that order will
3725        // always be correct.
3726        Collections.sort(mTmpRecents, mTaskRecordComparator);
3727
3728        // Go through and fix up the linked list.
3729        // The first one is the end of the chain and has no next.
3730        final TaskRecord first = mTmpRecents.get(0);
3731        first.inRecents = true;
3732        if (first.mNextAffiliate != null) {
3733            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3734            first.setNextAffiliate(null);
3735            notifyTaskPersisterLocked(first, false);
3736        }
3737        // Everything in the middle is doubly linked from next to prev.
3738        final int tmpSize = mTmpRecents.size();
3739        for (int i = 0; i < tmpSize - 1; ++i) {
3740            final TaskRecord next = mTmpRecents.get(i);
3741            final TaskRecord prev = mTmpRecents.get(i + 1);
3742            if (next.mPrevAffiliate != prev) {
3743                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3744                        " setting prev=" + prev);
3745                next.setPrevAffiliate(prev);
3746                notifyTaskPersisterLocked(next, false);
3747            }
3748            if (prev.mNextAffiliate != next) {
3749                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3750                        " setting next=" + next);
3751                prev.setNextAffiliate(next);
3752                notifyTaskPersisterLocked(prev, false);
3753            }
3754            prev.inRecents = true;
3755        }
3756        // The last one is the beginning of the list and has no prev.
3757        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3758        if (last.mPrevAffiliate != null) {
3759            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3760            last.setPrevAffiliate(null);
3761            notifyTaskPersisterLocked(last, false);
3762        }
3763
3764        // Insert the group back into mRecentTasks at start.
3765        mRecentTasks.addAll(start, mTmpRecents);
3766
3767        // Let the caller know where we left off.
3768        return start + tmpSize;
3769    }
3770
3771    /**
3772     * Update the recent tasks lists: make sure tasks should still be here (their
3773     * applications / activities still exist), update their availability, fixup ordering
3774     * of affiliations.
3775     */
3776    void cleanupRecentTasksLocked(int userId) {
3777        if (mRecentTasks == null) {
3778            // Happens when called from the packagemanager broadcast before boot.
3779            return;
3780        }
3781
3782        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3783        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3784        final IPackageManager pm = AppGlobals.getPackageManager();
3785        final ActivityInfo dummyAct = new ActivityInfo();
3786        final ApplicationInfo dummyApp = new ApplicationInfo();
3787
3788        int N = mRecentTasks.size();
3789
3790        int[] users = userId == UserHandle.USER_ALL
3791                ? getUsersLocked() : new int[] { userId };
3792        for (int user : users) {
3793            for (int i = 0; i < N; i++) {
3794                TaskRecord task = mRecentTasks.get(i);
3795                if (task.userId != user) {
3796                    // Only look at tasks for the user ID of interest.
3797                    continue;
3798                }
3799                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3800                    // This situation is broken, and we should just get rid of it now.
3801                    mRecentTasks.remove(i);
3802                    task.removedFromRecents();
3803                    i--;
3804                    N--;
3805                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3806                    continue;
3807                }
3808                // Check whether this activity is currently available.
3809                if (task.realActivity != null) {
3810                    ActivityInfo ai = availActCache.get(task.realActivity);
3811                    if (ai == null) {
3812                        try {
3813                            ai = pm.getActivityInfo(task.realActivity,
3814                                    PackageManager.GET_UNINSTALLED_PACKAGES
3815                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3816                        } catch (RemoteException e) {
3817                            // Will never happen.
3818                            continue;
3819                        }
3820                        if (ai == null) {
3821                            ai = dummyAct;
3822                        }
3823                        availActCache.put(task.realActivity, ai);
3824                    }
3825                    if (ai == dummyAct) {
3826                        // This could be either because the activity no longer exists, or the
3827                        // app is temporarily gone.  For the former we want to remove the recents
3828                        // entry; for the latter we want to mark it as unavailable.
3829                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3830                        if (app == null) {
3831                            try {
3832                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3833                                        PackageManager.GET_UNINSTALLED_PACKAGES
3834                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3835                            } catch (RemoteException e) {
3836                                // Will never happen.
3837                                continue;
3838                            }
3839                            if (app == null) {
3840                                app = dummyApp;
3841                            }
3842                            availAppCache.put(task.realActivity.getPackageName(), app);
3843                        }
3844                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3845                            // Doesn't exist any more!  Good-bye.
3846                            mRecentTasks.remove(i);
3847                            task.removedFromRecents();
3848                            i--;
3849                            N--;
3850                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3851                            continue;
3852                        } else {
3853                            // Otherwise just not available for now.
3854                            if (task.isAvailable) {
3855                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3856                                        + task);
3857                            }
3858                            task.isAvailable = false;
3859                        }
3860                    } else {
3861                        if (!ai.enabled || !ai.applicationInfo.enabled
3862                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3863                            if (task.isAvailable) {
3864                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3865                                        + task + " (enabled=" + ai.enabled + "/"
3866                                        + ai.applicationInfo.enabled +  " flags="
3867                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3868                            }
3869                            task.isAvailable = false;
3870                        } else {
3871                            if (!task.isAvailable) {
3872                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3873                                        + task);
3874                            }
3875                            task.isAvailable = true;
3876                        }
3877                    }
3878                }
3879            }
3880        }
3881
3882        // Verify the affiliate chain for each task.
3883        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3884        }
3885
3886        mTmpRecents.clear();
3887        // mRecentTasks is now in sorted, affiliated order.
3888    }
3889
3890    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3891        int N = mRecentTasks.size();
3892        TaskRecord top = task;
3893        int topIndex = taskIndex;
3894        while (top.mNextAffiliate != null && topIndex > 0) {
3895            top = top.mNextAffiliate;
3896            topIndex--;
3897        }
3898        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3899                + topIndex + " from intial " + taskIndex);
3900        // Find the end of the chain, doing a sanity check along the way.
3901        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3902        int endIndex = topIndex;
3903        TaskRecord prev = top;
3904        while (endIndex < N) {
3905            TaskRecord cur = mRecentTasks.get(endIndex);
3906            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3907                    + endIndex + " " + cur);
3908            if (cur == top) {
3909                // Verify start of the chain.
3910                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3911                    Slog.wtf(TAG, "Bad chain @" + endIndex
3912                            + ": first task has next affiliate: " + prev);
3913                    sane = false;
3914                    break;
3915                }
3916            } else {
3917                // Verify middle of the chain's next points back to the one before.
3918                if (cur.mNextAffiliate != prev
3919                        || cur.mNextAffiliateTaskId != prev.taskId) {
3920                    Slog.wtf(TAG, "Bad chain @" + endIndex
3921                            + ": middle task " + cur + " @" + endIndex
3922                            + " has bad next affiliate "
3923                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3924                            + ", expected " + prev);
3925                    sane = false;
3926                    break;
3927                }
3928            }
3929            if (cur.mPrevAffiliateTaskId == -1) {
3930                // Chain ends here.
3931                if (cur.mPrevAffiliate != null) {
3932                    Slog.wtf(TAG, "Bad chain @" + endIndex
3933                            + ": last task " + cur + " has previous affiliate "
3934                            + cur.mPrevAffiliate);
3935                    sane = false;
3936                }
3937                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3938                break;
3939            } else {
3940                // Verify middle of the chain's prev points to a valid item.
3941                if (cur.mPrevAffiliate == null) {
3942                    Slog.wtf(TAG, "Bad chain @" + endIndex
3943                            + ": task " + cur + " has previous affiliate "
3944                            + cur.mPrevAffiliate + " but should be id "
3945                            + cur.mPrevAffiliate);
3946                    sane = false;
3947                    break;
3948                }
3949            }
3950            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3951                Slog.wtf(TAG, "Bad chain @" + endIndex
3952                        + ": task " + cur + " has affiliated id "
3953                        + cur.mAffiliatedTaskId + " but should be "
3954                        + task.mAffiliatedTaskId);
3955                sane = false;
3956                break;
3957            }
3958            prev = cur;
3959            endIndex++;
3960            if (endIndex >= N) {
3961                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3962                        + ": last task " + prev);
3963                sane = false;
3964                break;
3965            }
3966        }
3967        if (sane) {
3968            if (endIndex < taskIndex) {
3969                Slog.wtf(TAG, "Bad chain @" + endIndex
3970                        + ": did not extend to task " + task + " @" + taskIndex);
3971                sane = false;
3972            }
3973        }
3974        if (sane) {
3975            // All looks good, we can just move all of the affiliated tasks
3976            // to the top.
3977            for (int i=topIndex; i<=endIndex; i++) {
3978                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3979                        + " from " + i + " to " + (i-topIndex));
3980                TaskRecord cur = mRecentTasks.remove(i);
3981                mRecentTasks.add(i-topIndex, cur);
3982            }
3983            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3984                    + " to " + endIndex);
3985            return true;
3986        }
3987
3988        // Whoops, couldn't do it.
3989        return false;
3990    }
3991
3992    final void addRecentTaskLocked(TaskRecord task) {
3993        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
3994                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
3995
3996        int N = mRecentTasks.size();
3997        // Quick case: check if the top-most recent task is the same.
3998        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
3999            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4000            return;
4001        }
4002        // Another quick case: check if this is part of a set of affiliated
4003        // tasks that are at the top.
4004        if (isAffiliated && N > 0 && task.inRecents
4005                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4006            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4007                    + " at top when adding " + task);
4008            return;
4009        }
4010        // Another quick case: never add voice sessions.
4011        if (task.voiceSession != null) {
4012            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4013            return;
4014        }
4015
4016        boolean needAffiliationFix = false;
4017
4018        // Slightly less quick case: the task is already in recents, so all we need
4019        // to do is move it.
4020        if (task.inRecents) {
4021            int taskIndex = mRecentTasks.indexOf(task);
4022            if (taskIndex >= 0) {
4023                if (!isAffiliated) {
4024                    // Simple case: this is not an affiliated task, so we just move it to the front.
4025                    mRecentTasks.remove(taskIndex);
4026                    mRecentTasks.add(0, task);
4027                    notifyTaskPersisterLocked(task, false);
4028                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4029                            + " from " + taskIndex);
4030                    return;
4031                } else {
4032                    // More complicated: need to keep all affiliated tasks together.
4033                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4034                        // All went well.
4035                        return;
4036                    }
4037
4038                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4039                    // everything and then go through our general path of adding a new task.
4040                    needAffiliationFix = true;
4041                }
4042            } else {
4043                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4044                needAffiliationFix = true;
4045            }
4046        }
4047
4048        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4049        trimRecentsForTaskLocked(task, true);
4050
4051        N = mRecentTasks.size();
4052        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4053            final TaskRecord tr = mRecentTasks.remove(N - 1);
4054            tr.removedFromRecents();
4055            N--;
4056        }
4057        task.inRecents = true;
4058        if (!isAffiliated || needAffiliationFix) {
4059            // If this is a simple non-affiliated task, or we had some failure trying to
4060            // handle it as part of an affilated task, then just place it at the top.
4061            mRecentTasks.add(0, task);
4062        } else if (isAffiliated) {
4063            // If this is a new affiliated task, then move all of the affiliated tasks
4064            // to the front and insert this new one.
4065            TaskRecord other = task.mNextAffiliate;
4066            if (other == null) {
4067                other = task.mPrevAffiliate;
4068            }
4069            if (other != null) {
4070                int otherIndex = mRecentTasks.indexOf(other);
4071                if (otherIndex >= 0) {
4072                    // Insert new task at appropriate location.
4073                    int taskIndex;
4074                    if (other == task.mNextAffiliate) {
4075                        // We found the index of our next affiliation, which is who is
4076                        // before us in the list, so add after that point.
4077                        taskIndex = otherIndex+1;
4078                    } else {
4079                        // We found the index of our previous affiliation, which is who is
4080                        // after us in the list, so add at their position.
4081                        taskIndex = otherIndex;
4082                    }
4083                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4084                            + taskIndex + ": " + task);
4085                    mRecentTasks.add(taskIndex, task);
4086
4087                    // Now move everything to the front.
4088                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4089                        // All went well.
4090                        return;
4091                    }
4092
4093                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4094                    // everything and then go through our general path of adding a new task.
4095                    needAffiliationFix = true;
4096                } else {
4097                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4098                            + other);
4099                    needAffiliationFix = true;
4100                }
4101            } else {
4102                if (DEBUG_RECENTS) Slog.d(TAG,
4103                        "addRecent: adding affiliated task without next/prev:" + task);
4104                needAffiliationFix = true;
4105            }
4106        }
4107        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4108
4109        if (needAffiliationFix) {
4110            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4111            cleanupRecentTasksLocked(task.userId);
4112        }
4113    }
4114
4115    /**
4116     * If needed, remove oldest existing entries in recents that are for the same kind
4117     * of task as the given one.
4118     */
4119    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4120        int N = mRecentTasks.size();
4121        final Intent intent = task.intent;
4122        final boolean document = intent != null && intent.isDocument();
4123
4124        int maxRecents = task.maxRecents - 1;
4125        for (int i=0; i<N; i++) {
4126            final TaskRecord tr = mRecentTasks.get(i);
4127            if (task != tr) {
4128                if (task.userId != tr.userId) {
4129                    continue;
4130                }
4131                if (i > MAX_RECENT_BITMAPS) {
4132                    tr.freeLastThumbnail();
4133                }
4134                final Intent trIntent = tr.intent;
4135                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4136                    (intent == null || !intent.filterEquals(trIntent))) {
4137                    continue;
4138                }
4139                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4140                if (document && trIsDocument) {
4141                    // These are the same document activity (not necessarily the same doc).
4142                    if (maxRecents > 0) {
4143                        --maxRecents;
4144                        continue;
4145                    }
4146                    // Hit the maximum number of documents for this task. Fall through
4147                    // and remove this document from recents.
4148                } else if (document || trIsDocument) {
4149                    // Only one of these is a document. Not the droid we're looking for.
4150                    continue;
4151                }
4152            }
4153
4154            if (!doTrim) {
4155                // If the caller is not actually asking for a trim, just tell them we reached
4156                // a point where the trim would happen.
4157                return i;
4158            }
4159
4160            // Either task and tr are the same or, their affinities match or their intents match
4161            // and neither of them is a document, or they are documents using the same activity
4162            // and their maxRecents has been reached.
4163            tr.disposeThumbnail();
4164            mRecentTasks.remove(i);
4165            if (task != tr) {
4166                tr.removedFromRecents();
4167            }
4168            i--;
4169            N--;
4170            if (task.intent == null) {
4171                // If the new recent task we are adding is not fully
4172                // specified, then replace it with the existing recent task.
4173                task = tr;
4174            }
4175            notifyTaskPersisterLocked(tr, false);
4176        }
4177
4178        return -1;
4179    }
4180
4181    @Override
4182    public void reportActivityFullyDrawn(IBinder token) {
4183        synchronized (this) {
4184            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4185            if (r == null) {
4186                return;
4187            }
4188            r.reportFullyDrawnLocked();
4189        }
4190    }
4191
4192    @Override
4193    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4194        synchronized (this) {
4195            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4196            if (r == null) {
4197                return;
4198            }
4199            final long origId = Binder.clearCallingIdentity();
4200            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4201            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4202                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4203            if (config != null) {
4204                r.frozenBeforeDestroy = true;
4205                if (!updateConfigurationLocked(config, r, false, false)) {
4206                    mStackSupervisor.resumeTopActivitiesLocked();
4207                }
4208            }
4209            Binder.restoreCallingIdentity(origId);
4210        }
4211    }
4212
4213    @Override
4214    public int getRequestedOrientation(IBinder token) {
4215        synchronized (this) {
4216            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4217            if (r == null) {
4218                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4219            }
4220            return mWindowManager.getAppOrientation(r.appToken);
4221        }
4222    }
4223
4224    /**
4225     * This is the internal entry point for handling Activity.finish().
4226     *
4227     * @param token The Binder token referencing the Activity we want to finish.
4228     * @param resultCode Result code, if any, from this Activity.
4229     * @param resultData Result data (Intent), if any, from this Activity.
4230     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4231     *            the root Activity in the task.
4232     *
4233     * @return Returns true if the activity successfully finished, or false if it is still running.
4234     */
4235    @Override
4236    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4237            boolean finishTask) {
4238        // Refuse possible leaked file descriptors
4239        if (resultData != null && resultData.hasFileDescriptors() == true) {
4240            throw new IllegalArgumentException("File descriptors passed in Intent");
4241        }
4242
4243        synchronized(this) {
4244            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4245            if (r == null) {
4246                return true;
4247            }
4248            // Keep track of the root activity of the task before we finish it
4249            TaskRecord tr = r.task;
4250            ActivityRecord rootR = tr.getRootActivity();
4251            if (rootR == null) {
4252                Slog.w(TAG, "Finishing task with all activities already finished");
4253            }
4254            // Do not allow task to finish in Lock Task mode.
4255            if (tr == mStackSupervisor.mLockTaskModeTask) {
4256                if (rootR == r) {
4257                    Slog.i(TAG, "Not finishing task in lock task mode");
4258                    mStackSupervisor.showLockTaskToast();
4259                    return false;
4260                }
4261            }
4262            if (mController != null) {
4263                // Find the first activity that is not finishing.
4264                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4265                if (next != null) {
4266                    // ask watcher if this is allowed
4267                    boolean resumeOK = true;
4268                    try {
4269                        resumeOK = mController.activityResuming(next.packageName);
4270                    } catch (RemoteException e) {
4271                        mController = null;
4272                        Watchdog.getInstance().setActivityController(null);
4273                    }
4274
4275                    if (!resumeOK) {
4276                        Slog.i(TAG, "Not finishing activity because controller resumed");
4277                        return false;
4278                    }
4279                }
4280            }
4281            final long origId = Binder.clearCallingIdentity();
4282            try {
4283                boolean res;
4284                if (finishTask && r == rootR) {
4285                    // If requested, remove the task that is associated to this activity only if it
4286                    // was the root activity in the task. The result code and data is ignored
4287                    // because we don't support returning them across task boundaries.
4288                    res = removeTaskByIdLocked(tr.taskId, false);
4289                    if (!res) {
4290                        Slog.i(TAG, "Removing task failed to finish activity");
4291                    }
4292                } else {
4293                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4294                            resultData, "app-request", true);
4295                    if (!res) {
4296                        Slog.i(TAG, "Failed to finish by app-request");
4297                    }
4298                }
4299                return res;
4300            } finally {
4301                Binder.restoreCallingIdentity(origId);
4302            }
4303        }
4304    }
4305
4306    @Override
4307    public final void finishHeavyWeightApp() {
4308        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4309                != PackageManager.PERMISSION_GRANTED) {
4310            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4311                    + Binder.getCallingPid()
4312                    + ", uid=" + Binder.getCallingUid()
4313                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4314            Slog.w(TAG, msg);
4315            throw new SecurityException(msg);
4316        }
4317
4318        synchronized(this) {
4319            if (mHeavyWeightProcess == null) {
4320                return;
4321            }
4322
4323            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4324                    mHeavyWeightProcess.activities);
4325            for (int i=0; i<activities.size(); i++) {
4326                ActivityRecord r = activities.get(i);
4327                if (!r.finishing) {
4328                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4329                            null, "finish-heavy", true);
4330                }
4331            }
4332
4333            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4334                    mHeavyWeightProcess.userId, 0));
4335            mHeavyWeightProcess = null;
4336        }
4337    }
4338
4339    @Override
4340    public void crashApplication(int uid, int initialPid, String packageName,
4341            String message) {
4342        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4343                != PackageManager.PERMISSION_GRANTED) {
4344            String msg = "Permission Denial: crashApplication() from pid="
4345                    + Binder.getCallingPid()
4346                    + ", uid=" + Binder.getCallingUid()
4347                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4348            Slog.w(TAG, msg);
4349            throw new SecurityException(msg);
4350        }
4351
4352        synchronized(this) {
4353            ProcessRecord proc = null;
4354
4355            // Figure out which process to kill.  We don't trust that initialPid
4356            // still has any relation to current pids, so must scan through the
4357            // list.
4358            synchronized (mPidsSelfLocked) {
4359                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4360                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4361                    if (p.uid != uid) {
4362                        continue;
4363                    }
4364                    if (p.pid == initialPid) {
4365                        proc = p;
4366                        break;
4367                    }
4368                    if (p.pkgList.containsKey(packageName)) {
4369                        proc = p;
4370                    }
4371                }
4372            }
4373
4374            if (proc == null) {
4375                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4376                        + " initialPid=" + initialPid
4377                        + " packageName=" + packageName);
4378                return;
4379            }
4380
4381            if (proc.thread != null) {
4382                if (proc.pid == Process.myPid()) {
4383                    Log.w(TAG, "crashApplication: trying to crash self!");
4384                    return;
4385                }
4386                long ident = Binder.clearCallingIdentity();
4387                try {
4388                    proc.thread.scheduleCrash(message);
4389                } catch (RemoteException e) {
4390                }
4391                Binder.restoreCallingIdentity(ident);
4392            }
4393        }
4394    }
4395
4396    @Override
4397    public final void finishSubActivity(IBinder token, String resultWho,
4398            int requestCode) {
4399        synchronized(this) {
4400            final long origId = Binder.clearCallingIdentity();
4401            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4402            if (r != null) {
4403                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4404            }
4405            Binder.restoreCallingIdentity(origId);
4406        }
4407    }
4408
4409    @Override
4410    public boolean finishActivityAffinity(IBinder token) {
4411        synchronized(this) {
4412            final long origId = Binder.clearCallingIdentity();
4413            try {
4414                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4415
4416                ActivityRecord rootR = r.task.getRootActivity();
4417                // Do not allow task to finish in Lock Task mode.
4418                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4419                    if (rootR == r) {
4420                        mStackSupervisor.showLockTaskToast();
4421                        return false;
4422                    }
4423                }
4424                boolean res = false;
4425                if (r != null) {
4426                    res = r.task.stack.finishActivityAffinityLocked(r);
4427                }
4428                return res;
4429            } finally {
4430                Binder.restoreCallingIdentity(origId);
4431            }
4432        }
4433    }
4434
4435    @Override
4436    public void finishVoiceTask(IVoiceInteractionSession session) {
4437        synchronized(this) {
4438            final long origId = Binder.clearCallingIdentity();
4439            try {
4440                mStackSupervisor.finishVoiceTask(session);
4441            } finally {
4442                Binder.restoreCallingIdentity(origId);
4443            }
4444        }
4445
4446    }
4447
4448    @Override
4449    public boolean releaseActivityInstance(IBinder token) {
4450        synchronized(this) {
4451            final long origId = Binder.clearCallingIdentity();
4452            try {
4453                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4454                if (r.task == null || r.task.stack == null) {
4455                    return false;
4456                }
4457                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4458            } finally {
4459                Binder.restoreCallingIdentity(origId);
4460            }
4461        }
4462    }
4463
4464    @Override
4465    public void releaseSomeActivities(IApplicationThread appInt) {
4466        synchronized(this) {
4467            final long origId = Binder.clearCallingIdentity();
4468            try {
4469                ProcessRecord app = getRecordForAppLocked(appInt);
4470                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4471            } finally {
4472                Binder.restoreCallingIdentity(origId);
4473            }
4474        }
4475    }
4476
4477    @Override
4478    public boolean willActivityBeVisible(IBinder token) {
4479        synchronized(this) {
4480            ActivityStack stack = ActivityRecord.getStackLocked(token);
4481            if (stack != null) {
4482                return stack.willActivityBeVisibleLocked(token);
4483            }
4484            return false;
4485        }
4486    }
4487
4488    @Override
4489    public void overridePendingTransition(IBinder token, String packageName,
4490            int enterAnim, int exitAnim) {
4491        synchronized(this) {
4492            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4493            if (self == null) {
4494                return;
4495            }
4496
4497            final long origId = Binder.clearCallingIdentity();
4498
4499            if (self.state == ActivityState.RESUMED
4500                    || self.state == ActivityState.PAUSING) {
4501                mWindowManager.overridePendingAppTransition(packageName,
4502                        enterAnim, exitAnim, null);
4503            }
4504
4505            Binder.restoreCallingIdentity(origId);
4506        }
4507    }
4508
4509    /**
4510     * Main function for removing an existing process from the activity manager
4511     * as a result of that process going away.  Clears out all connections
4512     * to the process.
4513     */
4514    private final void handleAppDiedLocked(ProcessRecord app,
4515            boolean restarting, boolean allowRestart) {
4516        int pid = app.pid;
4517        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4518        if (!kept && !restarting) {
4519            removeLruProcessLocked(app);
4520            if (pid > 0) {
4521                ProcessList.remove(pid);
4522            }
4523        }
4524
4525        if (mProfileProc == app) {
4526            clearProfilerLocked();
4527        }
4528
4529        // Remove this application's activities from active lists.
4530        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4531
4532        app.activities.clear();
4533
4534        if (app.instrumentationClass != null) {
4535            Slog.w(TAG, "Crash of app " + app.processName
4536                  + " running instrumentation " + app.instrumentationClass);
4537            Bundle info = new Bundle();
4538            info.putString("shortMsg", "Process crashed.");
4539            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4540        }
4541
4542        if (!restarting) {
4543            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4544                // If there was nothing to resume, and we are not already
4545                // restarting this process, but there is a visible activity that
4546                // is hosted by the process...  then make sure all visible
4547                // activities are running, taking care of restarting this
4548                // process.
4549                if (hasVisibleActivities) {
4550                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4551                }
4552            }
4553        }
4554    }
4555
4556    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4557        IBinder threadBinder = thread.asBinder();
4558        // Find the application record.
4559        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4560            ProcessRecord rec = mLruProcesses.get(i);
4561            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4562                return i;
4563            }
4564        }
4565        return -1;
4566    }
4567
4568    final ProcessRecord getRecordForAppLocked(
4569            IApplicationThread thread) {
4570        if (thread == null) {
4571            return null;
4572        }
4573
4574        int appIndex = getLRURecordIndexForAppLocked(thread);
4575        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4576    }
4577
4578    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4579        // If there are no longer any background processes running,
4580        // and the app that died was not running instrumentation,
4581        // then tell everyone we are now low on memory.
4582        boolean haveBg = false;
4583        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4584            ProcessRecord rec = mLruProcesses.get(i);
4585            if (rec.thread != null
4586                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4587                haveBg = true;
4588                break;
4589            }
4590        }
4591
4592        if (!haveBg) {
4593            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4594            if (doReport) {
4595                long now = SystemClock.uptimeMillis();
4596                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4597                    doReport = false;
4598                } else {
4599                    mLastMemUsageReportTime = now;
4600                }
4601            }
4602            final ArrayList<ProcessMemInfo> memInfos
4603                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4604            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4605            long now = SystemClock.uptimeMillis();
4606            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4607                ProcessRecord rec = mLruProcesses.get(i);
4608                if (rec == dyingProc || rec.thread == null) {
4609                    continue;
4610                }
4611                if (doReport) {
4612                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4613                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4614                }
4615                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4616                    // The low memory report is overriding any current
4617                    // state for a GC request.  Make sure to do
4618                    // heavy/important/visible/foreground processes first.
4619                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4620                        rec.lastRequestedGc = 0;
4621                    } else {
4622                        rec.lastRequestedGc = rec.lastLowMemory;
4623                    }
4624                    rec.reportLowMemory = true;
4625                    rec.lastLowMemory = now;
4626                    mProcessesToGc.remove(rec);
4627                    addProcessToGcListLocked(rec);
4628                }
4629            }
4630            if (doReport) {
4631                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4632                mHandler.sendMessage(msg);
4633            }
4634            scheduleAppGcsLocked();
4635        }
4636    }
4637
4638    final void appDiedLocked(ProcessRecord app) {
4639       appDiedLocked(app, app.pid, app.thread);
4640    }
4641
4642    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4643        // First check if this ProcessRecord is actually active for the pid.
4644        synchronized (mPidsSelfLocked) {
4645            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4646            if (curProc != app) {
4647                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4648                return;
4649            }
4650        }
4651
4652        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4653        synchronized (stats) {
4654            stats.noteProcessDiedLocked(app.info.uid, pid);
4655        }
4656
4657        Process.killProcessQuiet(pid);
4658        Process.killProcessGroup(app.info.uid, pid);
4659        app.killed = true;
4660
4661        // Clean up already done if the process has been re-started.
4662        if (app.pid == pid && app.thread != null &&
4663                app.thread.asBinder() == thread.asBinder()) {
4664            boolean doLowMem = app.instrumentationClass == null;
4665            boolean doOomAdj = doLowMem;
4666            if (!app.killedByAm) {
4667                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4668                        + ") has died");
4669                mAllowLowerMemLevel = true;
4670            } else {
4671                // Note that we always want to do oom adj to update our state with the
4672                // new number of procs.
4673                mAllowLowerMemLevel = false;
4674                doLowMem = false;
4675            }
4676            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4677            if (DEBUG_CLEANUP) Slog.v(
4678                TAG, "Dying app: " + app + ", pid: " + pid
4679                + ", thread: " + thread.asBinder());
4680            handleAppDiedLocked(app, false, true);
4681
4682            if (doOomAdj) {
4683                updateOomAdjLocked();
4684            }
4685            if (doLowMem) {
4686                doLowMemReportIfNeededLocked(app);
4687            }
4688        } else if (app.pid != pid) {
4689            // A new process has already been started.
4690            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4691                    + ") has died and restarted (pid " + app.pid + ").");
4692            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4693        } else if (DEBUG_PROCESSES) {
4694            Slog.d(TAG, "Received spurious death notification for thread "
4695                    + thread.asBinder());
4696        }
4697    }
4698
4699    /**
4700     * If a stack trace dump file is configured, dump process stack traces.
4701     * @param clearTraces causes the dump file to be erased prior to the new
4702     *    traces being written, if true; when false, the new traces will be
4703     *    appended to any existing file content.
4704     * @param firstPids of dalvik VM processes to dump stack traces for first
4705     * @param lastPids of dalvik VM processes to dump stack traces for last
4706     * @param nativeProcs optional list of native process names to dump stack crawls
4707     * @return file containing stack traces, or null if no dump file is configured
4708     */
4709    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4710            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4711        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4712        if (tracesPath == null || tracesPath.length() == 0) {
4713            return null;
4714        }
4715
4716        File tracesFile = new File(tracesPath);
4717        try {
4718            File tracesDir = tracesFile.getParentFile();
4719            if (!tracesDir.exists()) {
4720                tracesDir.mkdirs();
4721                if (!SELinux.restorecon(tracesDir)) {
4722                    return null;
4723                }
4724            }
4725            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4726
4727            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4728            tracesFile.createNewFile();
4729            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4730        } catch (IOException e) {
4731            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4732            return null;
4733        }
4734
4735        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4736        return tracesFile;
4737    }
4738
4739    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4740            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4741        // Use a FileObserver to detect when traces finish writing.
4742        // The order of traces is considered important to maintain for legibility.
4743        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4744            @Override
4745            public synchronized void onEvent(int event, String path) { notify(); }
4746        };
4747
4748        try {
4749            observer.startWatching();
4750
4751            // First collect all of the stacks of the most important pids.
4752            if (firstPids != null) {
4753                try {
4754                    int num = firstPids.size();
4755                    for (int i = 0; i < num; i++) {
4756                        synchronized (observer) {
4757                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4758                            observer.wait(200);  // Wait for write-close, give up after 200msec
4759                        }
4760                    }
4761                } catch (InterruptedException e) {
4762                    Slog.wtf(TAG, e);
4763                }
4764            }
4765
4766            // Next collect the stacks of the native pids
4767            if (nativeProcs != null) {
4768                int[] pids = Process.getPidsForCommands(nativeProcs);
4769                if (pids != null) {
4770                    for (int pid : pids) {
4771                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4772                    }
4773                }
4774            }
4775
4776            // Lastly, measure CPU usage.
4777            if (processCpuTracker != null) {
4778                processCpuTracker.init();
4779                System.gc();
4780                processCpuTracker.update();
4781                try {
4782                    synchronized (processCpuTracker) {
4783                        processCpuTracker.wait(500); // measure over 1/2 second.
4784                    }
4785                } catch (InterruptedException e) {
4786                }
4787                processCpuTracker.update();
4788
4789                // We'll take the stack crawls of just the top apps using CPU.
4790                final int N = processCpuTracker.countWorkingStats();
4791                int numProcs = 0;
4792                for (int i=0; i<N && numProcs<5; i++) {
4793                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4794                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4795                        numProcs++;
4796                        try {
4797                            synchronized (observer) {
4798                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4799                                observer.wait(200);  // Wait for write-close, give up after 200msec
4800                            }
4801                        } catch (InterruptedException e) {
4802                            Slog.wtf(TAG, e);
4803                        }
4804
4805                    }
4806                }
4807            }
4808        } finally {
4809            observer.stopWatching();
4810        }
4811    }
4812
4813    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4814        if (true || IS_USER_BUILD) {
4815            return;
4816        }
4817        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4818        if (tracesPath == null || tracesPath.length() == 0) {
4819            return;
4820        }
4821
4822        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4823        StrictMode.allowThreadDiskWrites();
4824        try {
4825            final File tracesFile = new File(tracesPath);
4826            final File tracesDir = tracesFile.getParentFile();
4827            final File tracesTmp = new File(tracesDir, "__tmp__");
4828            try {
4829                if (!tracesDir.exists()) {
4830                    tracesDir.mkdirs();
4831                    if (!SELinux.restorecon(tracesDir.getPath())) {
4832                        return;
4833                    }
4834                }
4835                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4836
4837                if (tracesFile.exists()) {
4838                    tracesTmp.delete();
4839                    tracesFile.renameTo(tracesTmp);
4840                }
4841                StringBuilder sb = new StringBuilder();
4842                Time tobj = new Time();
4843                tobj.set(System.currentTimeMillis());
4844                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4845                sb.append(": ");
4846                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4847                sb.append(" since ");
4848                sb.append(msg);
4849                FileOutputStream fos = new FileOutputStream(tracesFile);
4850                fos.write(sb.toString().getBytes());
4851                if (app == null) {
4852                    fos.write("\n*** No application process!".getBytes());
4853                }
4854                fos.close();
4855                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4856            } catch (IOException e) {
4857                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4858                return;
4859            }
4860
4861            if (app != null) {
4862                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4863                firstPids.add(app.pid);
4864                dumpStackTraces(tracesPath, firstPids, null, null, null);
4865            }
4866
4867            File lastTracesFile = null;
4868            File curTracesFile = null;
4869            for (int i=9; i>=0; i--) {
4870                String name = String.format(Locale.US, "slow%02d.txt", i);
4871                curTracesFile = new File(tracesDir, name);
4872                if (curTracesFile.exists()) {
4873                    if (lastTracesFile != null) {
4874                        curTracesFile.renameTo(lastTracesFile);
4875                    } else {
4876                        curTracesFile.delete();
4877                    }
4878                }
4879                lastTracesFile = curTracesFile;
4880            }
4881            tracesFile.renameTo(curTracesFile);
4882            if (tracesTmp.exists()) {
4883                tracesTmp.renameTo(tracesFile);
4884            }
4885        } finally {
4886            StrictMode.setThreadPolicy(oldPolicy);
4887        }
4888    }
4889
4890    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4891            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4892        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4893        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4894
4895        if (mController != null) {
4896            try {
4897                // 0 == continue, -1 = kill process immediately
4898                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4899                if (res < 0 && app.pid != MY_PID) {
4900                    app.kill("anr", true);
4901                }
4902            } catch (RemoteException e) {
4903                mController = null;
4904                Watchdog.getInstance().setActivityController(null);
4905            }
4906        }
4907
4908        long anrTime = SystemClock.uptimeMillis();
4909        if (MONITOR_CPU_USAGE) {
4910            updateCpuStatsNow();
4911        }
4912
4913        synchronized (this) {
4914            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4915            if (mShuttingDown) {
4916                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4917                return;
4918            } else if (app.notResponding) {
4919                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4920                return;
4921            } else if (app.crashing) {
4922                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4923                return;
4924            }
4925
4926            // In case we come through here for the same app before completing
4927            // this one, mark as anring now so we will bail out.
4928            app.notResponding = true;
4929
4930            // Log the ANR to the event log.
4931            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4932                    app.processName, app.info.flags, annotation);
4933
4934            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4935            firstPids.add(app.pid);
4936
4937            int parentPid = app.pid;
4938            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4939            if (parentPid != app.pid) firstPids.add(parentPid);
4940
4941            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4942
4943            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4944                ProcessRecord r = mLruProcesses.get(i);
4945                if (r != null && r.thread != null) {
4946                    int pid = r.pid;
4947                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4948                        if (r.persistent) {
4949                            firstPids.add(pid);
4950                        } else {
4951                            lastPids.put(pid, Boolean.TRUE);
4952                        }
4953                    }
4954                }
4955            }
4956        }
4957
4958        // Log the ANR to the main log.
4959        StringBuilder info = new StringBuilder();
4960        info.setLength(0);
4961        info.append("ANR in ").append(app.processName);
4962        if (activity != null && activity.shortComponentName != null) {
4963            info.append(" (").append(activity.shortComponentName).append(")");
4964        }
4965        info.append("\n");
4966        info.append("PID: ").append(app.pid).append("\n");
4967        if (annotation != null) {
4968            info.append("Reason: ").append(annotation).append("\n");
4969        }
4970        if (parent != null && parent != activity) {
4971            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4972        }
4973
4974        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4975
4976        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4977                NATIVE_STACKS_OF_INTEREST);
4978
4979        String cpuInfo = null;
4980        if (MONITOR_CPU_USAGE) {
4981            updateCpuStatsNow();
4982            synchronized (mProcessCpuTracker) {
4983                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4984            }
4985            info.append(processCpuTracker.printCurrentLoad());
4986            info.append(cpuInfo);
4987        }
4988
4989        info.append(processCpuTracker.printCurrentState(anrTime));
4990
4991        Slog.e(TAG, info.toString());
4992        if (tracesFile == null) {
4993            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4994            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4995        }
4996
4997        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4998                cpuInfo, tracesFile, null);
4999
5000        if (mController != null) {
5001            try {
5002                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5003                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5004                if (res != 0) {
5005                    if (res < 0 && app.pid != MY_PID) {
5006                        app.kill("anr", true);
5007                    } else {
5008                        synchronized (this) {
5009                            mServices.scheduleServiceTimeoutLocked(app);
5010                        }
5011                    }
5012                    return;
5013                }
5014            } catch (RemoteException e) {
5015                mController = null;
5016                Watchdog.getInstance().setActivityController(null);
5017            }
5018        }
5019
5020        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5021        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5022                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5023
5024        synchronized (this) {
5025            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5026                app.kill("bg anr", true);
5027                return;
5028            }
5029
5030            // Set the app's notResponding state, and look up the errorReportReceiver
5031            makeAppNotRespondingLocked(app,
5032                    activity != null ? activity.shortComponentName : null,
5033                    annotation != null ? "ANR " + annotation : "ANR",
5034                    info.toString());
5035
5036            // Bring up the infamous App Not Responding dialog
5037            Message msg = Message.obtain();
5038            HashMap<String, Object> map = new HashMap<String, Object>();
5039            msg.what = SHOW_NOT_RESPONDING_MSG;
5040            msg.obj = map;
5041            msg.arg1 = aboveSystem ? 1 : 0;
5042            map.put("app", app);
5043            if (activity != null) {
5044                map.put("activity", activity);
5045            }
5046
5047            mHandler.sendMessage(msg);
5048        }
5049    }
5050
5051    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5052        if (!mLaunchWarningShown) {
5053            mLaunchWarningShown = true;
5054            mHandler.post(new Runnable() {
5055                @Override
5056                public void run() {
5057                    synchronized (ActivityManagerService.this) {
5058                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5059                        d.show();
5060                        mHandler.postDelayed(new Runnable() {
5061                            @Override
5062                            public void run() {
5063                                synchronized (ActivityManagerService.this) {
5064                                    d.dismiss();
5065                                    mLaunchWarningShown = false;
5066                                }
5067                            }
5068                        }, 4000);
5069                    }
5070                }
5071            });
5072        }
5073    }
5074
5075    @Override
5076    public boolean clearApplicationUserData(final String packageName,
5077            final IPackageDataObserver observer, int userId) {
5078        enforceNotIsolatedCaller("clearApplicationUserData");
5079        int uid = Binder.getCallingUid();
5080        int pid = Binder.getCallingPid();
5081        userId = handleIncomingUser(pid, uid,
5082                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5083        long callingId = Binder.clearCallingIdentity();
5084        try {
5085            IPackageManager pm = AppGlobals.getPackageManager();
5086            int pkgUid = -1;
5087            synchronized(this) {
5088                try {
5089                    pkgUid = pm.getPackageUid(packageName, userId);
5090                } catch (RemoteException e) {
5091                }
5092                if (pkgUid == -1) {
5093                    Slog.w(TAG, "Invalid packageName: " + packageName);
5094                    if (observer != null) {
5095                        try {
5096                            observer.onRemoveCompleted(packageName, false);
5097                        } catch (RemoteException e) {
5098                            Slog.i(TAG, "Observer no longer exists.");
5099                        }
5100                    }
5101                    return false;
5102                }
5103                if (uid == pkgUid || checkComponentPermission(
5104                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5105                        pid, uid, -1, true)
5106                        == PackageManager.PERMISSION_GRANTED) {
5107                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5108                } else {
5109                    throw new SecurityException("PID " + pid + " does not have permission "
5110                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5111                                    + " of package " + packageName);
5112                }
5113
5114                // Remove all tasks match the cleared application package and user
5115                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5116                    final TaskRecord tr = mRecentTasks.get(i);
5117                    final String taskPackageName =
5118                            tr.getBaseIntent().getComponent().getPackageName();
5119                    if (tr.userId != userId) continue;
5120                    if (!taskPackageName.equals(packageName)) continue;
5121                    removeTaskByIdLocked(tr.taskId, false);
5122                }
5123            }
5124
5125            try {
5126                // Clear application user data
5127                pm.clearApplicationUserData(packageName, observer, userId);
5128
5129                synchronized(this) {
5130                    // Remove all permissions granted from/to this package
5131                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5132                }
5133
5134                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5135                        Uri.fromParts("package", packageName, null));
5136                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5137                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5138                        null, null, 0, null, null, null, false, false, userId);
5139            } catch (RemoteException e) {
5140            }
5141        } finally {
5142            Binder.restoreCallingIdentity(callingId);
5143        }
5144        return true;
5145    }
5146
5147    @Override
5148    public void killBackgroundProcesses(final String packageName, int userId) {
5149        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5150                != PackageManager.PERMISSION_GRANTED &&
5151                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5152                        != PackageManager.PERMISSION_GRANTED) {
5153            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5154                    + Binder.getCallingPid()
5155                    + ", uid=" + Binder.getCallingUid()
5156                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5157            Slog.w(TAG, msg);
5158            throw new SecurityException(msg);
5159        }
5160
5161        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5162                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5163        long callingId = Binder.clearCallingIdentity();
5164        try {
5165            IPackageManager pm = AppGlobals.getPackageManager();
5166            synchronized(this) {
5167                int appId = -1;
5168                try {
5169                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5170                } catch (RemoteException e) {
5171                }
5172                if (appId == -1) {
5173                    Slog.w(TAG, "Invalid packageName: " + packageName);
5174                    return;
5175                }
5176                killPackageProcessesLocked(packageName, appId, userId,
5177                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5178            }
5179        } finally {
5180            Binder.restoreCallingIdentity(callingId);
5181        }
5182    }
5183
5184    @Override
5185    public void killAllBackgroundProcesses() {
5186        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5187                != PackageManager.PERMISSION_GRANTED) {
5188            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5189                    + Binder.getCallingPid()
5190                    + ", uid=" + Binder.getCallingUid()
5191                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5192            Slog.w(TAG, msg);
5193            throw new SecurityException(msg);
5194        }
5195
5196        long callingId = Binder.clearCallingIdentity();
5197        try {
5198            synchronized(this) {
5199                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5200                final int NP = mProcessNames.getMap().size();
5201                for (int ip=0; ip<NP; ip++) {
5202                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5203                    final int NA = apps.size();
5204                    for (int ia=0; ia<NA; ia++) {
5205                        ProcessRecord app = apps.valueAt(ia);
5206                        if (app.persistent) {
5207                            // we don't kill persistent processes
5208                            continue;
5209                        }
5210                        if (app.removed) {
5211                            procs.add(app);
5212                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5213                            app.removed = true;
5214                            procs.add(app);
5215                        }
5216                    }
5217                }
5218
5219                int N = procs.size();
5220                for (int i=0; i<N; i++) {
5221                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5222                }
5223                mAllowLowerMemLevel = true;
5224                updateOomAdjLocked();
5225                doLowMemReportIfNeededLocked(null);
5226            }
5227        } finally {
5228            Binder.restoreCallingIdentity(callingId);
5229        }
5230    }
5231
5232    @Override
5233    public void forceStopPackage(final String packageName, int userId) {
5234        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5235                != PackageManager.PERMISSION_GRANTED) {
5236            String msg = "Permission Denial: forceStopPackage() from pid="
5237                    + Binder.getCallingPid()
5238                    + ", uid=" + Binder.getCallingUid()
5239                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5240            Slog.w(TAG, msg);
5241            throw new SecurityException(msg);
5242        }
5243        final int callingPid = Binder.getCallingPid();
5244        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5245                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5246        long callingId = Binder.clearCallingIdentity();
5247        try {
5248            IPackageManager pm = AppGlobals.getPackageManager();
5249            synchronized(this) {
5250                int[] users = userId == UserHandle.USER_ALL
5251                        ? getUsersLocked() : new int[] { userId };
5252                for (int user : users) {
5253                    int pkgUid = -1;
5254                    try {
5255                        pkgUid = pm.getPackageUid(packageName, user);
5256                    } catch (RemoteException e) {
5257                    }
5258                    if (pkgUid == -1) {
5259                        Slog.w(TAG, "Invalid packageName: " + packageName);
5260                        continue;
5261                    }
5262                    try {
5263                        pm.setPackageStoppedState(packageName, true, user);
5264                    } catch (RemoteException e) {
5265                    } catch (IllegalArgumentException e) {
5266                        Slog.w(TAG, "Failed trying to unstop package "
5267                                + packageName + ": " + e);
5268                    }
5269                    if (isUserRunningLocked(user, false)) {
5270                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5271                    }
5272                }
5273            }
5274        } finally {
5275            Binder.restoreCallingIdentity(callingId);
5276        }
5277    }
5278
5279    @Override
5280    public void addPackageDependency(String packageName) {
5281        synchronized (this) {
5282            int callingPid = Binder.getCallingPid();
5283            if (callingPid == Process.myPid()) {
5284                //  Yeah, um, no.
5285                Slog.w(TAG, "Can't addPackageDependency on system process");
5286                return;
5287            }
5288            ProcessRecord proc;
5289            synchronized (mPidsSelfLocked) {
5290                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5291            }
5292            if (proc != null) {
5293                if (proc.pkgDeps == null) {
5294                    proc.pkgDeps = new ArraySet<String>(1);
5295                }
5296                proc.pkgDeps.add(packageName);
5297            }
5298        }
5299    }
5300
5301    /*
5302     * The pkg name and app id have to be specified.
5303     */
5304    @Override
5305    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5306        if (pkg == null) {
5307            return;
5308        }
5309        // Make sure the uid is valid.
5310        if (appid < 0) {
5311            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5312            return;
5313        }
5314        int callerUid = Binder.getCallingUid();
5315        // Only the system server can kill an application
5316        if (callerUid == Process.SYSTEM_UID) {
5317            // Post an aysnc message to kill the application
5318            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5319            msg.arg1 = appid;
5320            msg.arg2 = 0;
5321            Bundle bundle = new Bundle();
5322            bundle.putString("pkg", pkg);
5323            bundle.putString("reason", reason);
5324            msg.obj = bundle;
5325            mHandler.sendMessage(msg);
5326        } else {
5327            throw new SecurityException(callerUid + " cannot kill pkg: " +
5328                    pkg);
5329        }
5330    }
5331
5332    @Override
5333    public void closeSystemDialogs(String reason) {
5334        enforceNotIsolatedCaller("closeSystemDialogs");
5335
5336        final int pid = Binder.getCallingPid();
5337        final int uid = Binder.getCallingUid();
5338        final long origId = Binder.clearCallingIdentity();
5339        try {
5340            synchronized (this) {
5341                // Only allow this from foreground processes, so that background
5342                // applications can't abuse it to prevent system UI from being shown.
5343                if (uid >= Process.FIRST_APPLICATION_UID) {
5344                    ProcessRecord proc;
5345                    synchronized (mPidsSelfLocked) {
5346                        proc = mPidsSelfLocked.get(pid);
5347                    }
5348                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5349                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5350                                + " from background process " + proc);
5351                        return;
5352                    }
5353                }
5354                closeSystemDialogsLocked(reason);
5355            }
5356        } finally {
5357            Binder.restoreCallingIdentity(origId);
5358        }
5359    }
5360
5361    void closeSystemDialogsLocked(String reason) {
5362        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5363        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5364                | Intent.FLAG_RECEIVER_FOREGROUND);
5365        if (reason != null) {
5366            intent.putExtra("reason", reason);
5367        }
5368        mWindowManager.closeSystemDialogs(reason);
5369
5370        mStackSupervisor.closeSystemDialogsLocked();
5371
5372        broadcastIntentLocked(null, null, intent, null,
5373                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5374                Process.SYSTEM_UID, UserHandle.USER_ALL);
5375    }
5376
5377    @Override
5378    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5379        enforceNotIsolatedCaller("getProcessMemoryInfo");
5380        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5381        for (int i=pids.length-1; i>=0; i--) {
5382            ProcessRecord proc;
5383            int oomAdj;
5384            synchronized (this) {
5385                synchronized (mPidsSelfLocked) {
5386                    proc = mPidsSelfLocked.get(pids[i]);
5387                    oomAdj = proc != null ? proc.setAdj : 0;
5388                }
5389            }
5390            infos[i] = new Debug.MemoryInfo();
5391            Debug.getMemoryInfo(pids[i], infos[i]);
5392            if (proc != null) {
5393                synchronized (this) {
5394                    if (proc.thread != null && proc.setAdj == oomAdj) {
5395                        // Record this for posterity if the process has been stable.
5396                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5397                                infos[i].getTotalUss(), false, proc.pkgList);
5398                    }
5399                }
5400            }
5401        }
5402        return infos;
5403    }
5404
5405    @Override
5406    public long[] getProcessPss(int[] pids) {
5407        enforceNotIsolatedCaller("getProcessPss");
5408        long[] pss = new long[pids.length];
5409        for (int i=pids.length-1; i>=0; i--) {
5410            ProcessRecord proc;
5411            int oomAdj;
5412            synchronized (this) {
5413                synchronized (mPidsSelfLocked) {
5414                    proc = mPidsSelfLocked.get(pids[i]);
5415                    oomAdj = proc != null ? proc.setAdj : 0;
5416                }
5417            }
5418            long[] tmpUss = new long[1];
5419            pss[i] = Debug.getPss(pids[i], tmpUss);
5420            if (proc != null) {
5421                synchronized (this) {
5422                    if (proc.thread != null && proc.setAdj == oomAdj) {
5423                        // Record this for posterity if the process has been stable.
5424                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5425                    }
5426                }
5427            }
5428        }
5429        return pss;
5430    }
5431
5432    @Override
5433    public void killApplicationProcess(String processName, int uid) {
5434        if (processName == null) {
5435            return;
5436        }
5437
5438        int callerUid = Binder.getCallingUid();
5439        // Only the system server can kill an application
5440        if (callerUid == Process.SYSTEM_UID) {
5441            synchronized (this) {
5442                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5443                if (app != null && app.thread != null) {
5444                    try {
5445                        app.thread.scheduleSuicide();
5446                    } catch (RemoteException e) {
5447                        // If the other end already died, then our work here is done.
5448                    }
5449                } else {
5450                    Slog.w(TAG, "Process/uid not found attempting kill of "
5451                            + processName + " / " + uid);
5452                }
5453            }
5454        } else {
5455            throw new SecurityException(callerUid + " cannot kill app process: " +
5456                    processName);
5457        }
5458    }
5459
5460    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5461        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5462                false, true, false, false, UserHandle.getUserId(uid), reason);
5463        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5464                Uri.fromParts("package", packageName, null));
5465        if (!mProcessesReady) {
5466            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5467                    | Intent.FLAG_RECEIVER_FOREGROUND);
5468        }
5469        intent.putExtra(Intent.EXTRA_UID, uid);
5470        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5471        broadcastIntentLocked(null, null, intent,
5472                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5473                false, false,
5474                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5475    }
5476
5477    private void forceStopUserLocked(int userId, String reason) {
5478        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5479        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5480        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5481                | Intent.FLAG_RECEIVER_FOREGROUND);
5482        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5483        broadcastIntentLocked(null, null, intent,
5484                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5485                false, false,
5486                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5487    }
5488
5489    private final boolean killPackageProcessesLocked(String packageName, int appId,
5490            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5491            boolean doit, boolean evenPersistent, String reason) {
5492        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5493
5494        // Remove all processes this package may have touched: all with the
5495        // same UID (except for the system or root user), and all whose name
5496        // matches the package name.
5497        final int NP = mProcessNames.getMap().size();
5498        for (int ip=0; ip<NP; ip++) {
5499            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5500            final int NA = apps.size();
5501            for (int ia=0; ia<NA; ia++) {
5502                ProcessRecord app = apps.valueAt(ia);
5503                if (app.persistent && !evenPersistent) {
5504                    // we don't kill persistent processes
5505                    continue;
5506                }
5507                if (app.removed) {
5508                    if (doit) {
5509                        procs.add(app);
5510                    }
5511                    continue;
5512                }
5513
5514                // Skip process if it doesn't meet our oom adj requirement.
5515                if (app.setAdj < minOomAdj) {
5516                    continue;
5517                }
5518
5519                // If no package is specified, we call all processes under the
5520                // give user id.
5521                if (packageName == null) {
5522                    if (app.userId != userId) {
5523                        continue;
5524                    }
5525                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5526                        continue;
5527                    }
5528                // Package has been specified, we want to hit all processes
5529                // that match it.  We need to qualify this by the processes
5530                // that are running under the specified app and user ID.
5531                } else {
5532                    final boolean isDep = app.pkgDeps != null
5533                            && app.pkgDeps.contains(packageName);
5534                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5535                        continue;
5536                    }
5537                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5538                        continue;
5539                    }
5540                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5541                        continue;
5542                    }
5543                }
5544
5545                // Process has passed all conditions, kill it!
5546                if (!doit) {
5547                    return true;
5548                }
5549                app.removed = true;
5550                procs.add(app);
5551            }
5552        }
5553
5554        int N = procs.size();
5555        for (int i=0; i<N; i++) {
5556            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5557        }
5558        updateOomAdjLocked();
5559        return N > 0;
5560    }
5561
5562    private final boolean forceStopPackageLocked(String name, int appId,
5563            boolean callerWillRestart, boolean purgeCache, boolean doit,
5564            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5565        int i;
5566        int N;
5567
5568        if (userId == UserHandle.USER_ALL && name == null) {
5569            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5570        }
5571
5572        if (appId < 0 && name != null) {
5573            try {
5574                appId = UserHandle.getAppId(
5575                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5576            } catch (RemoteException e) {
5577            }
5578        }
5579
5580        if (doit) {
5581            if (name != null) {
5582                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5583                        + " user=" + userId + ": " + reason);
5584            } else {
5585                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5586            }
5587
5588            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5589            for (int ip=pmap.size()-1; ip>=0; ip--) {
5590                SparseArray<Long> ba = pmap.valueAt(ip);
5591                for (i=ba.size()-1; i>=0; i--) {
5592                    boolean remove = false;
5593                    final int entUid = ba.keyAt(i);
5594                    if (name != null) {
5595                        if (userId == UserHandle.USER_ALL) {
5596                            if (UserHandle.getAppId(entUid) == appId) {
5597                                remove = true;
5598                            }
5599                        } else {
5600                            if (entUid == UserHandle.getUid(userId, appId)) {
5601                                remove = true;
5602                            }
5603                        }
5604                    } else if (UserHandle.getUserId(entUid) == userId) {
5605                        remove = true;
5606                    }
5607                    if (remove) {
5608                        ba.removeAt(i);
5609                    }
5610                }
5611                if (ba.size() == 0) {
5612                    pmap.removeAt(ip);
5613                }
5614            }
5615        }
5616
5617        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5618                -100, callerWillRestart, true, doit, evenPersistent,
5619                name == null ? ("stop user " + userId) : ("stop " + name));
5620
5621        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5622            if (!doit) {
5623                return true;
5624            }
5625            didSomething = true;
5626        }
5627
5628        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5629            if (!doit) {
5630                return true;
5631            }
5632            didSomething = true;
5633        }
5634
5635        if (name == null) {
5636            // Remove all sticky broadcasts from this user.
5637            mStickyBroadcasts.remove(userId);
5638        }
5639
5640        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5641        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5642                userId, providers)) {
5643            if (!doit) {
5644                return true;
5645            }
5646            didSomething = true;
5647        }
5648        N = providers.size();
5649        for (i=0; i<N; i++) {
5650            removeDyingProviderLocked(null, providers.get(i), true);
5651        }
5652
5653        // Remove transient permissions granted from/to this package/user
5654        removeUriPermissionsForPackageLocked(name, userId, false);
5655
5656        if (name == null || uninstalling) {
5657            // Remove pending intents.  For now we only do this when force
5658            // stopping users, because we have some problems when doing this
5659            // for packages -- app widgets are not currently cleaned up for
5660            // such packages, so they can be left with bad pending intents.
5661            if (mIntentSenderRecords.size() > 0) {
5662                Iterator<WeakReference<PendingIntentRecord>> it
5663                        = mIntentSenderRecords.values().iterator();
5664                while (it.hasNext()) {
5665                    WeakReference<PendingIntentRecord> wpir = it.next();
5666                    if (wpir == null) {
5667                        it.remove();
5668                        continue;
5669                    }
5670                    PendingIntentRecord pir = wpir.get();
5671                    if (pir == null) {
5672                        it.remove();
5673                        continue;
5674                    }
5675                    if (name == null) {
5676                        // Stopping user, remove all objects for the user.
5677                        if (pir.key.userId != userId) {
5678                            // Not the same user, skip it.
5679                            continue;
5680                        }
5681                    } else {
5682                        if (UserHandle.getAppId(pir.uid) != appId) {
5683                            // Different app id, skip it.
5684                            continue;
5685                        }
5686                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5687                            // Different user, skip it.
5688                            continue;
5689                        }
5690                        if (!pir.key.packageName.equals(name)) {
5691                            // Different package, skip it.
5692                            continue;
5693                        }
5694                    }
5695                    if (!doit) {
5696                        return true;
5697                    }
5698                    didSomething = true;
5699                    it.remove();
5700                    pir.canceled = true;
5701                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5702                        pir.key.activity.pendingResults.remove(pir.ref);
5703                    }
5704                }
5705            }
5706        }
5707
5708        if (doit) {
5709            if (purgeCache && name != null) {
5710                AttributeCache ac = AttributeCache.instance();
5711                if (ac != null) {
5712                    ac.removePackage(name);
5713                }
5714            }
5715            if (mBooted) {
5716                mStackSupervisor.resumeTopActivitiesLocked();
5717                mStackSupervisor.scheduleIdleLocked();
5718            }
5719        }
5720
5721        return didSomething;
5722    }
5723
5724    private final boolean removeProcessLocked(ProcessRecord app,
5725            boolean callerWillRestart, boolean allowRestart, String reason) {
5726        final String name = app.processName;
5727        final int uid = app.uid;
5728        if (DEBUG_PROCESSES) Slog.d(
5729            TAG, "Force removing proc " + app.toShortString() + " (" + name
5730            + "/" + uid + ")");
5731
5732        mProcessNames.remove(name, uid);
5733        mIsolatedProcesses.remove(app.uid);
5734        if (mHeavyWeightProcess == app) {
5735            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5736                    mHeavyWeightProcess.userId, 0));
5737            mHeavyWeightProcess = null;
5738        }
5739        boolean needRestart = false;
5740        if (app.pid > 0 && app.pid != MY_PID) {
5741            int pid = app.pid;
5742            synchronized (mPidsSelfLocked) {
5743                mPidsSelfLocked.remove(pid);
5744                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5745            }
5746            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5747            if (app.isolated) {
5748                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5749            }
5750            app.kill(reason, true);
5751            handleAppDiedLocked(app, true, allowRestart);
5752            removeLruProcessLocked(app);
5753
5754            if (app.persistent && !app.isolated) {
5755                if (!callerWillRestart) {
5756                    addAppLocked(app.info, false, null /* ABI override */);
5757                } else {
5758                    needRestart = true;
5759                }
5760            }
5761        } else {
5762            mRemovedProcesses.add(app);
5763        }
5764
5765        return needRestart;
5766    }
5767
5768    private final void processStartTimedOutLocked(ProcessRecord app) {
5769        final int pid = app.pid;
5770        boolean gone = false;
5771        synchronized (mPidsSelfLocked) {
5772            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5773            if (knownApp != null && knownApp.thread == null) {
5774                mPidsSelfLocked.remove(pid);
5775                gone = true;
5776            }
5777        }
5778
5779        if (gone) {
5780            Slog.w(TAG, "Process " + app + " failed to attach");
5781            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5782                    pid, app.uid, app.processName);
5783            mProcessNames.remove(app.processName, app.uid);
5784            mIsolatedProcesses.remove(app.uid);
5785            if (mHeavyWeightProcess == app) {
5786                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5787                        mHeavyWeightProcess.userId, 0));
5788                mHeavyWeightProcess = null;
5789            }
5790            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5791            if (app.isolated) {
5792                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5793            }
5794            // Take care of any launching providers waiting for this process.
5795            checkAppInLaunchingProvidersLocked(app, true);
5796            // Take care of any services that are waiting for the process.
5797            mServices.processStartTimedOutLocked(app);
5798            app.kill("start timeout", true);
5799            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5800                Slog.w(TAG, "Unattached app died before backup, skipping");
5801                try {
5802                    IBackupManager bm = IBackupManager.Stub.asInterface(
5803                            ServiceManager.getService(Context.BACKUP_SERVICE));
5804                    bm.agentDisconnected(app.info.packageName);
5805                } catch (RemoteException e) {
5806                    // Can't happen; the backup manager is local
5807                }
5808            }
5809            if (isPendingBroadcastProcessLocked(pid)) {
5810                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5811                skipPendingBroadcastLocked(pid);
5812            }
5813        } else {
5814            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5815        }
5816    }
5817
5818    private final boolean attachApplicationLocked(IApplicationThread thread,
5819            int pid) {
5820
5821        // Find the application record that is being attached...  either via
5822        // the pid if we are running in multiple processes, or just pull the
5823        // next app record if we are emulating process with anonymous threads.
5824        ProcessRecord app;
5825        if (pid != MY_PID && pid >= 0) {
5826            synchronized (mPidsSelfLocked) {
5827                app = mPidsSelfLocked.get(pid);
5828            }
5829        } else {
5830            app = null;
5831        }
5832
5833        if (app == null) {
5834            Slog.w(TAG, "No pending application record for pid " + pid
5835                    + " (IApplicationThread " + thread + "); dropping process");
5836            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5837            if (pid > 0 && pid != MY_PID) {
5838                Process.killProcessQuiet(pid);
5839                //TODO: Process.killProcessGroup(app.info.uid, pid);
5840            } else {
5841                try {
5842                    thread.scheduleExit();
5843                } catch (Exception e) {
5844                    // Ignore exceptions.
5845                }
5846            }
5847            return false;
5848        }
5849
5850        // If this application record is still attached to a previous
5851        // process, clean it up now.
5852        if (app.thread != null) {
5853            handleAppDiedLocked(app, true, true);
5854        }
5855
5856        // Tell the process all about itself.
5857
5858        if (localLOGV) Slog.v(
5859                TAG, "Binding process pid " + pid + " to record " + app);
5860
5861        final String processName = app.processName;
5862        try {
5863            AppDeathRecipient adr = new AppDeathRecipient(
5864                    app, pid, thread);
5865            thread.asBinder().linkToDeath(adr, 0);
5866            app.deathRecipient = adr;
5867        } catch (RemoteException e) {
5868            app.resetPackageList(mProcessStats);
5869            startProcessLocked(app, "link fail", processName);
5870            return false;
5871        }
5872
5873        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5874
5875        app.makeActive(thread, mProcessStats);
5876        app.curAdj = app.setAdj = -100;
5877        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5878        app.forcingToForeground = null;
5879        updateProcessForegroundLocked(app, false, false);
5880        app.hasShownUi = false;
5881        app.debugging = false;
5882        app.cached = false;
5883        app.killedByAm = false;
5884
5885        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5886
5887        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5888        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5889
5890        if (!normalMode) {
5891            Slog.i(TAG, "Launching preboot mode app: " + app);
5892        }
5893
5894        if (localLOGV) Slog.v(
5895            TAG, "New app record " + app
5896            + " thread=" + thread.asBinder() + " pid=" + pid);
5897        try {
5898            int testMode = IApplicationThread.DEBUG_OFF;
5899            if (mDebugApp != null && mDebugApp.equals(processName)) {
5900                testMode = mWaitForDebugger
5901                    ? IApplicationThread.DEBUG_WAIT
5902                    : IApplicationThread.DEBUG_ON;
5903                app.debugging = true;
5904                if (mDebugTransient) {
5905                    mDebugApp = mOrigDebugApp;
5906                    mWaitForDebugger = mOrigWaitForDebugger;
5907                }
5908            }
5909            String profileFile = app.instrumentationProfileFile;
5910            ParcelFileDescriptor profileFd = null;
5911            int samplingInterval = 0;
5912            boolean profileAutoStop = false;
5913            if (mProfileApp != null && mProfileApp.equals(processName)) {
5914                mProfileProc = app;
5915                profileFile = mProfileFile;
5916                profileFd = mProfileFd;
5917                samplingInterval = mSamplingInterval;
5918                profileAutoStop = mAutoStopProfiler;
5919            }
5920            boolean enableOpenGlTrace = false;
5921            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5922                enableOpenGlTrace = true;
5923                mOpenGlTraceApp = null;
5924            }
5925
5926            // If the app is being launched for restore or full backup, set it up specially
5927            boolean isRestrictedBackupMode = false;
5928            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5929                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5930                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5931                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5932            }
5933
5934            ensurePackageDexOpt(app.instrumentationInfo != null
5935                    ? app.instrumentationInfo.packageName
5936                    : app.info.packageName);
5937            if (app.instrumentationClass != null) {
5938                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5939            }
5940            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5941                    + processName + " with config " + mConfiguration);
5942            ApplicationInfo appInfo = app.instrumentationInfo != null
5943                    ? app.instrumentationInfo : app.info;
5944            app.compat = compatibilityInfoForPackageLocked(appInfo);
5945            if (profileFd != null) {
5946                profileFd = profileFd.dup();
5947            }
5948            ProfilerInfo profilerInfo = profileFile == null ? null
5949                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5950            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5951                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5952                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5953                    isRestrictedBackupMode || !normalMode, app.persistent,
5954                    new Configuration(mConfiguration), app.compat,
5955                    getCommonServicesLocked(app.isolated),
5956                    mCoreSettingsObserver.getCoreSettingsLocked());
5957            updateLruProcessLocked(app, false, null);
5958            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5959        } catch (Exception e) {
5960            // todo: Yikes!  What should we do?  For now we will try to
5961            // start another process, but that could easily get us in
5962            // an infinite loop of restarting processes...
5963            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5964
5965            app.resetPackageList(mProcessStats);
5966            app.unlinkDeathRecipient();
5967            startProcessLocked(app, "bind fail", processName);
5968            return false;
5969        }
5970
5971        // Remove this record from the list of starting applications.
5972        mPersistentStartingProcesses.remove(app);
5973        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5974                "Attach application locked removing on hold: " + app);
5975        mProcessesOnHold.remove(app);
5976
5977        boolean badApp = false;
5978        boolean didSomething = false;
5979
5980        // See if the top visible activity is waiting to run in this process...
5981        if (normalMode) {
5982            try {
5983                if (mStackSupervisor.attachApplicationLocked(app)) {
5984                    didSomething = true;
5985                }
5986            } catch (Exception e) {
5987                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5988                badApp = true;
5989            }
5990        }
5991
5992        // Find any services that should be running in this process...
5993        if (!badApp) {
5994            try {
5995                didSomething |= mServices.attachApplicationLocked(app, processName);
5996            } catch (Exception e) {
5997                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5998                badApp = true;
5999            }
6000        }
6001
6002        // Check if a next-broadcast receiver is in this process...
6003        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6004            try {
6005                didSomething |= sendPendingBroadcastsLocked(app);
6006            } catch (Exception e) {
6007                // If the app died trying to launch the receiver we declare it 'bad'
6008                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6009                badApp = true;
6010            }
6011        }
6012
6013        // Check whether the next backup agent is in this process...
6014        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6015            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6016            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6017            try {
6018                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6019                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6020                        mBackupTarget.backupMode);
6021            } catch (Exception e) {
6022                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6023                badApp = true;
6024            }
6025        }
6026
6027        if (badApp) {
6028            app.kill("error during init", true);
6029            handleAppDiedLocked(app, false, true);
6030            return false;
6031        }
6032
6033        if (!didSomething) {
6034            updateOomAdjLocked();
6035        }
6036
6037        return true;
6038    }
6039
6040    @Override
6041    public final void attachApplication(IApplicationThread thread) {
6042        synchronized (this) {
6043            int callingPid = Binder.getCallingPid();
6044            final long origId = Binder.clearCallingIdentity();
6045            attachApplicationLocked(thread, callingPid);
6046            Binder.restoreCallingIdentity(origId);
6047        }
6048    }
6049
6050    @Override
6051    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6052        final long origId = Binder.clearCallingIdentity();
6053        synchronized (this) {
6054            ActivityStack stack = ActivityRecord.getStackLocked(token);
6055            if (stack != null) {
6056                ActivityRecord r =
6057                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6058                if (stopProfiling) {
6059                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6060                        try {
6061                            mProfileFd.close();
6062                        } catch (IOException e) {
6063                        }
6064                        clearProfilerLocked();
6065                    }
6066                }
6067            }
6068        }
6069        Binder.restoreCallingIdentity(origId);
6070    }
6071
6072    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6073        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6074                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6075    }
6076
6077    void enableScreenAfterBoot() {
6078        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6079                SystemClock.uptimeMillis());
6080        mWindowManager.enableScreenAfterBoot();
6081
6082        synchronized (this) {
6083            updateEventDispatchingLocked();
6084        }
6085    }
6086
6087    @Override
6088    public void showBootMessage(final CharSequence msg, final boolean always) {
6089        enforceNotIsolatedCaller("showBootMessage");
6090        mWindowManager.showBootMessage(msg, always);
6091    }
6092
6093    @Override
6094    public void keyguardWaitingForActivityDrawn() {
6095        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6096        final long token = Binder.clearCallingIdentity();
6097        try {
6098            synchronized (this) {
6099                if (DEBUG_LOCKSCREEN) logLockScreen("");
6100                mWindowManager.keyguardWaitingForActivityDrawn();
6101                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6102                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6103                    updateSleepIfNeededLocked();
6104                }
6105            }
6106        } finally {
6107            Binder.restoreCallingIdentity(token);
6108        }
6109    }
6110
6111    final void finishBooting() {
6112        synchronized (this) {
6113            if (!mBootAnimationComplete) {
6114                mCallFinishBooting = true;
6115                return;
6116            }
6117            mCallFinishBooting = false;
6118        }
6119
6120        ArraySet<String> completedIsas = new ArraySet<String>();
6121        for (String abi : Build.SUPPORTED_ABIS) {
6122            Process.establishZygoteConnectionForAbi(abi);
6123            final String instructionSet = VMRuntime.getInstructionSet(abi);
6124            if (!completedIsas.contains(instructionSet)) {
6125                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6126                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6127                }
6128                completedIsas.add(instructionSet);
6129            }
6130        }
6131
6132        IntentFilter pkgFilter = new IntentFilter();
6133        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6134        pkgFilter.addDataScheme("package");
6135        mContext.registerReceiver(new BroadcastReceiver() {
6136            @Override
6137            public void onReceive(Context context, Intent intent) {
6138                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6139                if (pkgs != null) {
6140                    for (String pkg : pkgs) {
6141                        synchronized (ActivityManagerService.this) {
6142                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6143                                    0, "finished booting")) {
6144                                setResultCode(Activity.RESULT_OK);
6145                                return;
6146                            }
6147                        }
6148                    }
6149                }
6150            }
6151        }, pkgFilter);
6152
6153        // Let system services know.
6154        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6155
6156        synchronized (this) {
6157            // Ensure that any processes we had put on hold are now started
6158            // up.
6159            final int NP = mProcessesOnHold.size();
6160            if (NP > 0) {
6161                ArrayList<ProcessRecord> procs =
6162                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6163                for (int ip=0; ip<NP; ip++) {
6164                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6165                            + procs.get(ip));
6166                    startProcessLocked(procs.get(ip), "on-hold", null);
6167                }
6168            }
6169
6170            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6171                // Start looking for apps that are abusing wake locks.
6172                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6173                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6174                // Tell anyone interested that we are done booting!
6175                SystemProperties.set("sys.boot_completed", "1");
6176
6177                // And trigger dev.bootcomplete if we are not showing encryption progress
6178                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6179                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6180                    SystemProperties.set("dev.bootcomplete", "1");
6181                }
6182                for (int i=0; i<mStartedUsers.size(); i++) {
6183                    UserStartedState uss = mStartedUsers.valueAt(i);
6184                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6185                        uss.mState = UserStartedState.STATE_RUNNING;
6186                        final int userId = mStartedUsers.keyAt(i);
6187                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6188                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6189                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6190                        broadcastIntentLocked(null, null, intent, null,
6191                                new IIntentReceiver.Stub() {
6192                                    @Override
6193                                    public void performReceive(Intent intent, int resultCode,
6194                                            String data, Bundle extras, boolean ordered,
6195                                            boolean sticky, int sendingUser) {
6196                                        synchronized (ActivityManagerService.this) {
6197                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6198                                                    true, false);
6199                                        }
6200                                    }
6201                                },
6202                                0, null, null,
6203                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6204                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6205                                userId);
6206                    }
6207                }
6208                scheduleStartProfilesLocked();
6209            }
6210        }
6211    }
6212
6213    @Override
6214    public void bootAnimationComplete() {
6215        final boolean callFinishBooting;
6216        synchronized (this) {
6217            callFinishBooting = mCallFinishBooting;
6218            mBootAnimationComplete = true;
6219        }
6220        if (callFinishBooting) {
6221            finishBooting();
6222        }
6223    }
6224
6225    final void ensureBootCompleted() {
6226        boolean booting;
6227        boolean enableScreen;
6228        synchronized (this) {
6229            booting = mBooting;
6230            mBooting = false;
6231            enableScreen = !mBooted;
6232            mBooted = true;
6233        }
6234
6235        if (booting) {
6236            finishBooting();
6237        }
6238
6239        if (enableScreen) {
6240            enableScreenAfterBoot();
6241        }
6242    }
6243
6244    @Override
6245    public final void activityResumed(IBinder token) {
6246        final long origId = Binder.clearCallingIdentity();
6247        synchronized(this) {
6248            ActivityStack stack = ActivityRecord.getStackLocked(token);
6249            if (stack != null) {
6250                ActivityRecord.activityResumedLocked(token);
6251            }
6252        }
6253        Binder.restoreCallingIdentity(origId);
6254    }
6255
6256    @Override
6257    public final void activityPaused(IBinder token) {
6258        final long origId = Binder.clearCallingIdentity();
6259        synchronized(this) {
6260            ActivityStack stack = ActivityRecord.getStackLocked(token);
6261            if (stack != null) {
6262                stack.activityPausedLocked(token, false);
6263            }
6264        }
6265        Binder.restoreCallingIdentity(origId);
6266    }
6267
6268    @Override
6269    public final void activityStopped(IBinder token, Bundle icicle,
6270            PersistableBundle persistentState, CharSequence description) {
6271        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6272
6273        // Refuse possible leaked file descriptors
6274        if (icicle != null && icicle.hasFileDescriptors()) {
6275            throw new IllegalArgumentException("File descriptors passed in Bundle");
6276        }
6277
6278        final long origId = Binder.clearCallingIdentity();
6279
6280        synchronized (this) {
6281            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6282            if (r != null) {
6283                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6284            }
6285        }
6286
6287        trimApplications();
6288
6289        Binder.restoreCallingIdentity(origId);
6290    }
6291
6292    @Override
6293    public final void activityDestroyed(IBinder token) {
6294        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6295        synchronized (this) {
6296            ActivityStack stack = ActivityRecord.getStackLocked(token);
6297            if (stack != null) {
6298                stack.activityDestroyedLocked(token);
6299            }
6300        }
6301    }
6302
6303    @Override
6304    public final void backgroundResourcesReleased(IBinder token) {
6305        final long origId = Binder.clearCallingIdentity();
6306        try {
6307            synchronized (this) {
6308                ActivityStack stack = ActivityRecord.getStackLocked(token);
6309                if (stack != null) {
6310                    stack.backgroundResourcesReleased();
6311                }
6312            }
6313        } finally {
6314            Binder.restoreCallingIdentity(origId);
6315        }
6316    }
6317
6318    @Override
6319    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6320        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6321    }
6322
6323    @Override
6324    public final void notifyEnterAnimationComplete(IBinder token) {
6325        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6326    }
6327
6328    @Override
6329    public String getCallingPackage(IBinder token) {
6330        synchronized (this) {
6331            ActivityRecord r = getCallingRecordLocked(token);
6332            return r != null ? r.info.packageName : null;
6333        }
6334    }
6335
6336    @Override
6337    public ComponentName getCallingActivity(IBinder token) {
6338        synchronized (this) {
6339            ActivityRecord r = getCallingRecordLocked(token);
6340            return r != null ? r.intent.getComponent() : null;
6341        }
6342    }
6343
6344    private ActivityRecord getCallingRecordLocked(IBinder token) {
6345        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6346        if (r == null) {
6347            return null;
6348        }
6349        return r.resultTo;
6350    }
6351
6352    @Override
6353    public ComponentName getActivityClassForToken(IBinder token) {
6354        synchronized(this) {
6355            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6356            if (r == null) {
6357                return null;
6358            }
6359            return r.intent.getComponent();
6360        }
6361    }
6362
6363    @Override
6364    public String getPackageForToken(IBinder token) {
6365        synchronized(this) {
6366            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6367            if (r == null) {
6368                return null;
6369            }
6370            return r.packageName;
6371        }
6372    }
6373
6374    @Override
6375    public IIntentSender getIntentSender(int type,
6376            String packageName, IBinder token, String resultWho,
6377            int requestCode, Intent[] intents, String[] resolvedTypes,
6378            int flags, Bundle options, int userId) {
6379        enforceNotIsolatedCaller("getIntentSender");
6380        // Refuse possible leaked file descriptors
6381        if (intents != null) {
6382            if (intents.length < 1) {
6383                throw new IllegalArgumentException("Intents array length must be >= 1");
6384            }
6385            for (int i=0; i<intents.length; i++) {
6386                Intent intent = intents[i];
6387                if (intent != null) {
6388                    if (intent.hasFileDescriptors()) {
6389                        throw new IllegalArgumentException("File descriptors passed in Intent");
6390                    }
6391                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6392                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6393                        throw new IllegalArgumentException(
6394                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6395                    }
6396                    intents[i] = new Intent(intent);
6397                }
6398            }
6399            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6400                throw new IllegalArgumentException(
6401                        "Intent array length does not match resolvedTypes length");
6402            }
6403        }
6404        if (options != null) {
6405            if (options.hasFileDescriptors()) {
6406                throw new IllegalArgumentException("File descriptors passed in options");
6407            }
6408        }
6409
6410        synchronized(this) {
6411            int callingUid = Binder.getCallingUid();
6412            int origUserId = userId;
6413            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6414                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6415                    ALLOW_NON_FULL, "getIntentSender", null);
6416            if (origUserId == UserHandle.USER_CURRENT) {
6417                // We don't want to evaluate this until the pending intent is
6418                // actually executed.  However, we do want to always do the
6419                // security checking for it above.
6420                userId = UserHandle.USER_CURRENT;
6421            }
6422            try {
6423                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6424                    int uid = AppGlobals.getPackageManager()
6425                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6426                    if (!UserHandle.isSameApp(callingUid, uid)) {
6427                        String msg = "Permission Denial: getIntentSender() from pid="
6428                            + Binder.getCallingPid()
6429                            + ", uid=" + Binder.getCallingUid()
6430                            + ", (need uid=" + uid + ")"
6431                            + " is not allowed to send as package " + packageName;
6432                        Slog.w(TAG, msg);
6433                        throw new SecurityException(msg);
6434                    }
6435                }
6436
6437                return getIntentSenderLocked(type, packageName, callingUid, userId,
6438                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6439
6440            } catch (RemoteException e) {
6441                throw new SecurityException(e);
6442            }
6443        }
6444    }
6445
6446    IIntentSender getIntentSenderLocked(int type, String packageName,
6447            int callingUid, int userId, IBinder token, String resultWho,
6448            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6449            Bundle options) {
6450        if (DEBUG_MU)
6451            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6452        ActivityRecord activity = null;
6453        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6454            activity = ActivityRecord.isInStackLocked(token);
6455            if (activity == null) {
6456                return null;
6457            }
6458            if (activity.finishing) {
6459                return null;
6460            }
6461        }
6462
6463        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6464        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6465        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6466        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6467                |PendingIntent.FLAG_UPDATE_CURRENT);
6468
6469        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6470                type, packageName, activity, resultWho,
6471                requestCode, intents, resolvedTypes, flags, options, userId);
6472        WeakReference<PendingIntentRecord> ref;
6473        ref = mIntentSenderRecords.get(key);
6474        PendingIntentRecord rec = ref != null ? ref.get() : null;
6475        if (rec != null) {
6476            if (!cancelCurrent) {
6477                if (updateCurrent) {
6478                    if (rec.key.requestIntent != null) {
6479                        rec.key.requestIntent.replaceExtras(intents != null ?
6480                                intents[intents.length - 1] : null);
6481                    }
6482                    if (intents != null) {
6483                        intents[intents.length-1] = rec.key.requestIntent;
6484                        rec.key.allIntents = intents;
6485                        rec.key.allResolvedTypes = resolvedTypes;
6486                    } else {
6487                        rec.key.allIntents = null;
6488                        rec.key.allResolvedTypes = null;
6489                    }
6490                }
6491                return rec;
6492            }
6493            rec.canceled = true;
6494            mIntentSenderRecords.remove(key);
6495        }
6496        if (noCreate) {
6497            return rec;
6498        }
6499        rec = new PendingIntentRecord(this, key, callingUid);
6500        mIntentSenderRecords.put(key, rec.ref);
6501        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6502            if (activity.pendingResults == null) {
6503                activity.pendingResults
6504                        = new HashSet<WeakReference<PendingIntentRecord>>();
6505            }
6506            activity.pendingResults.add(rec.ref);
6507        }
6508        return rec;
6509    }
6510
6511    @Override
6512    public void cancelIntentSender(IIntentSender sender) {
6513        if (!(sender instanceof PendingIntentRecord)) {
6514            return;
6515        }
6516        synchronized(this) {
6517            PendingIntentRecord rec = (PendingIntentRecord)sender;
6518            try {
6519                int uid = AppGlobals.getPackageManager()
6520                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6521                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6522                    String msg = "Permission Denial: cancelIntentSender() from pid="
6523                        + Binder.getCallingPid()
6524                        + ", uid=" + Binder.getCallingUid()
6525                        + " is not allowed to cancel packges "
6526                        + rec.key.packageName;
6527                    Slog.w(TAG, msg);
6528                    throw new SecurityException(msg);
6529                }
6530            } catch (RemoteException e) {
6531                throw new SecurityException(e);
6532            }
6533            cancelIntentSenderLocked(rec, true);
6534        }
6535    }
6536
6537    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6538        rec.canceled = true;
6539        mIntentSenderRecords.remove(rec.key);
6540        if (cleanActivity && rec.key.activity != null) {
6541            rec.key.activity.pendingResults.remove(rec.ref);
6542        }
6543    }
6544
6545    @Override
6546    public String getPackageForIntentSender(IIntentSender pendingResult) {
6547        if (!(pendingResult instanceof PendingIntentRecord)) {
6548            return null;
6549        }
6550        try {
6551            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6552            return res.key.packageName;
6553        } catch (ClassCastException e) {
6554        }
6555        return null;
6556    }
6557
6558    @Override
6559    public int getUidForIntentSender(IIntentSender sender) {
6560        if (sender instanceof PendingIntentRecord) {
6561            try {
6562                PendingIntentRecord res = (PendingIntentRecord)sender;
6563                return res.uid;
6564            } catch (ClassCastException e) {
6565            }
6566        }
6567        return -1;
6568    }
6569
6570    @Override
6571    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6572        if (!(pendingResult instanceof PendingIntentRecord)) {
6573            return false;
6574        }
6575        try {
6576            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6577            if (res.key.allIntents == null) {
6578                return false;
6579            }
6580            for (int i=0; i<res.key.allIntents.length; i++) {
6581                Intent intent = res.key.allIntents[i];
6582                if (intent.getPackage() != null && intent.getComponent() != null) {
6583                    return false;
6584                }
6585            }
6586            return true;
6587        } catch (ClassCastException e) {
6588        }
6589        return false;
6590    }
6591
6592    @Override
6593    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6594        if (!(pendingResult instanceof PendingIntentRecord)) {
6595            return false;
6596        }
6597        try {
6598            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6599            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6600                return true;
6601            }
6602            return false;
6603        } catch (ClassCastException e) {
6604        }
6605        return false;
6606    }
6607
6608    @Override
6609    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6610        if (!(pendingResult instanceof PendingIntentRecord)) {
6611            return null;
6612        }
6613        try {
6614            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6615            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6616        } catch (ClassCastException e) {
6617        }
6618        return null;
6619    }
6620
6621    @Override
6622    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6623        if (!(pendingResult instanceof PendingIntentRecord)) {
6624            return null;
6625        }
6626        try {
6627            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6628            Intent intent = res.key.requestIntent;
6629            if (intent != null) {
6630                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6631                        || res.lastTagPrefix.equals(prefix))) {
6632                    return res.lastTag;
6633                }
6634                res.lastTagPrefix = prefix;
6635                StringBuilder sb = new StringBuilder(128);
6636                if (prefix != null) {
6637                    sb.append(prefix);
6638                }
6639                if (intent.getAction() != null) {
6640                    sb.append(intent.getAction());
6641                } else if (intent.getComponent() != null) {
6642                    intent.getComponent().appendShortString(sb);
6643                } else {
6644                    sb.append("?");
6645                }
6646                return res.lastTag = sb.toString();
6647            }
6648        } catch (ClassCastException e) {
6649        }
6650        return null;
6651    }
6652
6653    @Override
6654    public void setProcessLimit(int max) {
6655        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6656                "setProcessLimit()");
6657        synchronized (this) {
6658            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6659            mProcessLimitOverride = max;
6660        }
6661        trimApplications();
6662    }
6663
6664    @Override
6665    public int getProcessLimit() {
6666        synchronized (this) {
6667            return mProcessLimitOverride;
6668        }
6669    }
6670
6671    void foregroundTokenDied(ForegroundToken token) {
6672        synchronized (ActivityManagerService.this) {
6673            synchronized (mPidsSelfLocked) {
6674                ForegroundToken cur
6675                    = mForegroundProcesses.get(token.pid);
6676                if (cur != token) {
6677                    return;
6678                }
6679                mForegroundProcesses.remove(token.pid);
6680                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6681                if (pr == null) {
6682                    return;
6683                }
6684                pr.forcingToForeground = null;
6685                updateProcessForegroundLocked(pr, false, false);
6686            }
6687            updateOomAdjLocked();
6688        }
6689    }
6690
6691    @Override
6692    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6693        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6694                "setProcessForeground()");
6695        synchronized(this) {
6696            boolean changed = false;
6697
6698            synchronized (mPidsSelfLocked) {
6699                ProcessRecord pr = mPidsSelfLocked.get(pid);
6700                if (pr == null && isForeground) {
6701                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6702                    return;
6703                }
6704                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6705                if (oldToken != null) {
6706                    oldToken.token.unlinkToDeath(oldToken, 0);
6707                    mForegroundProcesses.remove(pid);
6708                    if (pr != null) {
6709                        pr.forcingToForeground = null;
6710                    }
6711                    changed = true;
6712                }
6713                if (isForeground && token != null) {
6714                    ForegroundToken newToken = new ForegroundToken() {
6715                        @Override
6716                        public void binderDied() {
6717                            foregroundTokenDied(this);
6718                        }
6719                    };
6720                    newToken.pid = pid;
6721                    newToken.token = token;
6722                    try {
6723                        token.linkToDeath(newToken, 0);
6724                        mForegroundProcesses.put(pid, newToken);
6725                        pr.forcingToForeground = token;
6726                        changed = true;
6727                    } catch (RemoteException e) {
6728                        // If the process died while doing this, we will later
6729                        // do the cleanup with the process death link.
6730                    }
6731                }
6732            }
6733
6734            if (changed) {
6735                updateOomAdjLocked();
6736            }
6737        }
6738    }
6739
6740    // =========================================================
6741    // PERMISSIONS
6742    // =========================================================
6743
6744    static class PermissionController extends IPermissionController.Stub {
6745        ActivityManagerService mActivityManagerService;
6746        PermissionController(ActivityManagerService activityManagerService) {
6747            mActivityManagerService = activityManagerService;
6748        }
6749
6750        @Override
6751        public boolean checkPermission(String permission, int pid, int uid) {
6752            return mActivityManagerService.checkPermission(permission, pid,
6753                    uid) == PackageManager.PERMISSION_GRANTED;
6754        }
6755    }
6756
6757    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6758        @Override
6759        public int checkComponentPermission(String permission, int pid, int uid,
6760                int owningUid, boolean exported) {
6761            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6762                    owningUid, exported);
6763        }
6764
6765        @Override
6766        public Object getAMSLock() {
6767            return ActivityManagerService.this;
6768        }
6769    }
6770
6771    /**
6772     * This can be called with or without the global lock held.
6773     */
6774    int checkComponentPermission(String permission, int pid, int uid,
6775            int owningUid, boolean exported) {
6776        if (pid == MY_PID) {
6777            return PackageManager.PERMISSION_GRANTED;
6778        }
6779        return ActivityManager.checkComponentPermission(permission, uid,
6780                owningUid, exported);
6781    }
6782
6783    /**
6784     * As the only public entry point for permissions checking, this method
6785     * can enforce the semantic that requesting a check on a null global
6786     * permission is automatically denied.  (Internally a null permission
6787     * string is used when calling {@link #checkComponentPermission} in cases
6788     * when only uid-based security is needed.)
6789     *
6790     * This can be called with or without the global lock held.
6791     */
6792    @Override
6793    public int checkPermission(String permission, int pid, int uid) {
6794        if (permission == null) {
6795            return PackageManager.PERMISSION_DENIED;
6796        }
6797        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6798    }
6799
6800    @Override
6801    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6802        if (permission == null) {
6803            return PackageManager.PERMISSION_DENIED;
6804        }
6805
6806        // We might be performing an operation on behalf of an indirect binder
6807        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6808        // client identity accordingly before proceeding.
6809        Identity tlsIdentity = sCallerIdentity.get();
6810        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6811            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6812                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6813            uid = tlsIdentity.uid;
6814            pid = tlsIdentity.pid;
6815        }
6816
6817        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6818    }
6819
6820    /**
6821     * Binder IPC calls go through the public entry point.
6822     * This can be called with or without the global lock held.
6823     */
6824    int checkCallingPermission(String permission) {
6825        return checkPermission(permission,
6826                Binder.getCallingPid(),
6827                UserHandle.getAppId(Binder.getCallingUid()));
6828    }
6829
6830    /**
6831     * This can be called with or without the global lock held.
6832     */
6833    void enforceCallingPermission(String permission, String func) {
6834        if (checkCallingPermission(permission)
6835                == PackageManager.PERMISSION_GRANTED) {
6836            return;
6837        }
6838
6839        String msg = "Permission Denial: " + func + " from pid="
6840                + Binder.getCallingPid()
6841                + ", uid=" + Binder.getCallingUid()
6842                + " requires " + permission;
6843        Slog.w(TAG, msg);
6844        throw new SecurityException(msg);
6845    }
6846
6847    /**
6848     * Determine if UID is holding permissions required to access {@link Uri} in
6849     * the given {@link ProviderInfo}. Final permission checking is always done
6850     * in {@link ContentProvider}.
6851     */
6852    private final boolean checkHoldingPermissionsLocked(
6853            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6854        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6855                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6856        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6857            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6858                    != PERMISSION_GRANTED) {
6859                return false;
6860            }
6861        }
6862        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6863    }
6864
6865    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6866            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6867        if (pi.applicationInfo.uid == uid) {
6868            return true;
6869        } else if (!pi.exported) {
6870            return false;
6871        }
6872
6873        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6874        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6875        try {
6876            // check if target holds top-level <provider> permissions
6877            if (!readMet && pi.readPermission != null && considerUidPermissions
6878                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6879                readMet = true;
6880            }
6881            if (!writeMet && pi.writePermission != null && considerUidPermissions
6882                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6883                writeMet = true;
6884            }
6885
6886            // track if unprotected read/write is allowed; any denied
6887            // <path-permission> below removes this ability
6888            boolean allowDefaultRead = pi.readPermission == null;
6889            boolean allowDefaultWrite = pi.writePermission == null;
6890
6891            // check if target holds any <path-permission> that match uri
6892            final PathPermission[] pps = pi.pathPermissions;
6893            if (pps != null) {
6894                final String path = grantUri.uri.getPath();
6895                int i = pps.length;
6896                while (i > 0 && (!readMet || !writeMet)) {
6897                    i--;
6898                    PathPermission pp = pps[i];
6899                    if (pp.match(path)) {
6900                        if (!readMet) {
6901                            final String pprperm = pp.getReadPermission();
6902                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6903                                    + pprperm + " for " + pp.getPath()
6904                                    + ": match=" + pp.match(path)
6905                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6906                            if (pprperm != null) {
6907                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6908                                        == PERMISSION_GRANTED) {
6909                                    readMet = true;
6910                                } else {
6911                                    allowDefaultRead = false;
6912                                }
6913                            }
6914                        }
6915                        if (!writeMet) {
6916                            final String ppwperm = pp.getWritePermission();
6917                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6918                                    + ppwperm + " for " + pp.getPath()
6919                                    + ": match=" + pp.match(path)
6920                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6921                            if (ppwperm != null) {
6922                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6923                                        == PERMISSION_GRANTED) {
6924                                    writeMet = true;
6925                                } else {
6926                                    allowDefaultWrite = false;
6927                                }
6928                            }
6929                        }
6930                    }
6931                }
6932            }
6933
6934            // grant unprotected <provider> read/write, if not blocked by
6935            // <path-permission> above
6936            if (allowDefaultRead) readMet = true;
6937            if (allowDefaultWrite) writeMet = true;
6938
6939        } catch (RemoteException e) {
6940            return false;
6941        }
6942
6943        return readMet && writeMet;
6944    }
6945
6946    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6947        ProviderInfo pi = null;
6948        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6949        if (cpr != null) {
6950            pi = cpr.info;
6951        } else {
6952            try {
6953                pi = AppGlobals.getPackageManager().resolveContentProvider(
6954                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6955            } catch (RemoteException ex) {
6956            }
6957        }
6958        return pi;
6959    }
6960
6961    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6962        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6963        if (targetUris != null) {
6964            return targetUris.get(grantUri);
6965        }
6966        return null;
6967    }
6968
6969    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6970            String targetPkg, int targetUid, GrantUri grantUri) {
6971        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6972        if (targetUris == null) {
6973            targetUris = Maps.newArrayMap();
6974            mGrantedUriPermissions.put(targetUid, targetUris);
6975        }
6976
6977        UriPermission perm = targetUris.get(grantUri);
6978        if (perm == null) {
6979            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6980            targetUris.put(grantUri, perm);
6981        }
6982
6983        return perm;
6984    }
6985
6986    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6987            final int modeFlags) {
6988        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6989        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6990                : UriPermission.STRENGTH_OWNED;
6991
6992        // Root gets to do everything.
6993        if (uid == 0) {
6994            return true;
6995        }
6996
6997        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6998        if (perms == null) return false;
6999
7000        // First look for exact match
7001        final UriPermission exactPerm = perms.get(grantUri);
7002        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7003            return true;
7004        }
7005
7006        // No exact match, look for prefixes
7007        final int N = perms.size();
7008        for (int i = 0; i < N; i++) {
7009            final UriPermission perm = perms.valueAt(i);
7010            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7011                    && perm.getStrength(modeFlags) >= minStrength) {
7012                return true;
7013            }
7014        }
7015
7016        return false;
7017    }
7018
7019    /**
7020     * @param uri This uri must NOT contain an embedded userId.
7021     * @param userId The userId in which the uri is to be resolved.
7022     */
7023    @Override
7024    public int checkUriPermission(Uri uri, int pid, int uid,
7025            final int modeFlags, int userId, IBinder callerToken) {
7026        enforceNotIsolatedCaller("checkUriPermission");
7027
7028        // Another redirected-binder-call permissions check as in
7029        // {@link checkPermissionWithToken}.
7030        Identity tlsIdentity = sCallerIdentity.get();
7031        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7032            uid = tlsIdentity.uid;
7033            pid = tlsIdentity.pid;
7034        }
7035
7036        // Our own process gets to do everything.
7037        if (pid == MY_PID) {
7038            return PackageManager.PERMISSION_GRANTED;
7039        }
7040        synchronized (this) {
7041            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7042                    ? PackageManager.PERMISSION_GRANTED
7043                    : PackageManager.PERMISSION_DENIED;
7044        }
7045    }
7046
7047    /**
7048     * Check if the targetPkg can be granted permission to access uri by
7049     * the callingUid using the given modeFlags.  Throws a security exception
7050     * if callingUid is not allowed to do this.  Returns the uid of the target
7051     * if the URI permission grant should be performed; returns -1 if it is not
7052     * needed (for example targetPkg already has permission to access the URI).
7053     * If you already know the uid of the target, you can supply it in
7054     * lastTargetUid else set that to -1.
7055     */
7056    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7057            final int modeFlags, int lastTargetUid) {
7058        if (!Intent.isAccessUriMode(modeFlags)) {
7059            return -1;
7060        }
7061
7062        if (targetPkg != null) {
7063            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7064                    "Checking grant " + targetPkg + " permission to " + grantUri);
7065        }
7066
7067        final IPackageManager pm = AppGlobals.getPackageManager();
7068
7069        // If this is not a content: uri, we can't do anything with it.
7070        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7071            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7072                    "Can't grant URI permission for non-content URI: " + grantUri);
7073            return -1;
7074        }
7075
7076        final String authority = grantUri.uri.getAuthority();
7077        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7078        if (pi == null) {
7079            Slog.w(TAG, "No content provider found for permission check: " +
7080                    grantUri.uri.toSafeString());
7081            return -1;
7082        }
7083
7084        int targetUid = lastTargetUid;
7085        if (targetUid < 0 && targetPkg != null) {
7086            try {
7087                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7088                if (targetUid < 0) {
7089                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7090                            "Can't grant URI permission no uid for: " + targetPkg);
7091                    return -1;
7092                }
7093            } catch (RemoteException ex) {
7094                return -1;
7095            }
7096        }
7097
7098        if (targetUid >= 0) {
7099            // First...  does the target actually need this permission?
7100            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7101                // No need to grant the target this permission.
7102                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7103                        "Target " + targetPkg + " already has full permission to " + grantUri);
7104                return -1;
7105            }
7106        } else {
7107            // First...  there is no target package, so can anyone access it?
7108            boolean allowed = pi.exported;
7109            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7110                if (pi.readPermission != null) {
7111                    allowed = false;
7112                }
7113            }
7114            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7115                if (pi.writePermission != null) {
7116                    allowed = false;
7117                }
7118            }
7119            if (allowed) {
7120                return -1;
7121            }
7122        }
7123
7124        /* There is a special cross user grant if:
7125         * - The target is on another user.
7126         * - Apps on the current user can access the uri without any uid permissions.
7127         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7128         * grant uri permissions.
7129         */
7130        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7131                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7132                modeFlags, false /*without considering the uid permissions*/);
7133
7134        // Second...  is the provider allowing granting of URI permissions?
7135        if (!specialCrossUserGrant) {
7136            if (!pi.grantUriPermissions) {
7137                throw new SecurityException("Provider " + pi.packageName
7138                        + "/" + pi.name
7139                        + " does not allow granting of Uri permissions (uri "
7140                        + grantUri + ")");
7141            }
7142            if (pi.uriPermissionPatterns != null) {
7143                final int N = pi.uriPermissionPatterns.length;
7144                boolean allowed = false;
7145                for (int i=0; i<N; i++) {
7146                    if (pi.uriPermissionPatterns[i] != null
7147                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7148                        allowed = true;
7149                        break;
7150                    }
7151                }
7152                if (!allowed) {
7153                    throw new SecurityException("Provider " + pi.packageName
7154                            + "/" + pi.name
7155                            + " does not allow granting of permission to path of Uri "
7156                            + grantUri);
7157                }
7158            }
7159        }
7160
7161        // Third...  does the caller itself have permission to access
7162        // this uri?
7163        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7164            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7165                // Require they hold a strong enough Uri permission
7166                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7167                    throw new SecurityException("Uid " + callingUid
7168                            + " does not have permission to uri " + grantUri);
7169                }
7170            }
7171        }
7172        return targetUid;
7173    }
7174
7175    /**
7176     * @param uri This uri must NOT contain an embedded userId.
7177     * @param userId The userId in which the uri is to be resolved.
7178     */
7179    @Override
7180    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7181            final int modeFlags, int userId) {
7182        enforceNotIsolatedCaller("checkGrantUriPermission");
7183        synchronized(this) {
7184            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7185                    new GrantUri(userId, uri, false), modeFlags, -1);
7186        }
7187    }
7188
7189    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7190            final int modeFlags, UriPermissionOwner owner) {
7191        if (!Intent.isAccessUriMode(modeFlags)) {
7192            return;
7193        }
7194
7195        // So here we are: the caller has the assumed permission
7196        // to the uri, and the target doesn't.  Let's now give this to
7197        // the target.
7198
7199        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7200                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7201
7202        final String authority = grantUri.uri.getAuthority();
7203        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7204        if (pi == null) {
7205            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7206            return;
7207        }
7208
7209        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7210            grantUri.prefix = true;
7211        }
7212        final UriPermission perm = findOrCreateUriPermissionLocked(
7213                pi.packageName, targetPkg, targetUid, grantUri);
7214        perm.grantModes(modeFlags, owner);
7215    }
7216
7217    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7218            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7219        if (targetPkg == null) {
7220            throw new NullPointerException("targetPkg");
7221        }
7222        int targetUid;
7223        final IPackageManager pm = AppGlobals.getPackageManager();
7224        try {
7225            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7226        } catch (RemoteException ex) {
7227            return;
7228        }
7229
7230        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7231                targetUid);
7232        if (targetUid < 0) {
7233            return;
7234        }
7235
7236        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7237                owner);
7238    }
7239
7240    static class NeededUriGrants extends ArrayList<GrantUri> {
7241        final String targetPkg;
7242        final int targetUid;
7243        final int flags;
7244
7245        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7246            this.targetPkg = targetPkg;
7247            this.targetUid = targetUid;
7248            this.flags = flags;
7249        }
7250    }
7251
7252    /**
7253     * Like checkGrantUriPermissionLocked, but takes an Intent.
7254     */
7255    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7256            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7257        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7258                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7259                + " clip=" + (intent != null ? intent.getClipData() : null)
7260                + " from " + intent + "; flags=0x"
7261                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7262
7263        if (targetPkg == null) {
7264            throw new NullPointerException("targetPkg");
7265        }
7266
7267        if (intent == null) {
7268            return null;
7269        }
7270        Uri data = intent.getData();
7271        ClipData clip = intent.getClipData();
7272        if (data == null && clip == null) {
7273            return null;
7274        }
7275        // Default userId for uris in the intent (if they don't specify it themselves)
7276        int contentUserHint = intent.getContentUserHint();
7277        if (contentUserHint == UserHandle.USER_CURRENT) {
7278            contentUserHint = UserHandle.getUserId(callingUid);
7279        }
7280        final IPackageManager pm = AppGlobals.getPackageManager();
7281        int targetUid;
7282        if (needed != null) {
7283            targetUid = needed.targetUid;
7284        } else {
7285            try {
7286                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7287            } catch (RemoteException ex) {
7288                return null;
7289            }
7290            if (targetUid < 0) {
7291                if (DEBUG_URI_PERMISSION) {
7292                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7293                            + " on user " + targetUserId);
7294                }
7295                return null;
7296            }
7297        }
7298        if (data != null) {
7299            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7300            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7301                    targetUid);
7302            if (targetUid > 0) {
7303                if (needed == null) {
7304                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7305                }
7306                needed.add(grantUri);
7307            }
7308        }
7309        if (clip != null) {
7310            for (int i=0; i<clip.getItemCount(); i++) {
7311                Uri uri = clip.getItemAt(i).getUri();
7312                if (uri != null) {
7313                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7314                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7315                            targetUid);
7316                    if (targetUid > 0) {
7317                        if (needed == null) {
7318                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7319                        }
7320                        needed.add(grantUri);
7321                    }
7322                } else {
7323                    Intent clipIntent = clip.getItemAt(i).getIntent();
7324                    if (clipIntent != null) {
7325                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7326                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7327                        if (newNeeded != null) {
7328                            needed = newNeeded;
7329                        }
7330                    }
7331                }
7332            }
7333        }
7334
7335        return needed;
7336    }
7337
7338    /**
7339     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7340     */
7341    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7342            UriPermissionOwner owner) {
7343        if (needed != null) {
7344            for (int i=0; i<needed.size(); i++) {
7345                GrantUri grantUri = needed.get(i);
7346                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7347                        grantUri, needed.flags, owner);
7348            }
7349        }
7350    }
7351
7352    void grantUriPermissionFromIntentLocked(int callingUid,
7353            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7354        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7355                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7356        if (needed == null) {
7357            return;
7358        }
7359
7360        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7361    }
7362
7363    /**
7364     * @param uri This uri must NOT contain an embedded userId.
7365     * @param userId The userId in which the uri is to be resolved.
7366     */
7367    @Override
7368    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7369            final int modeFlags, int userId) {
7370        enforceNotIsolatedCaller("grantUriPermission");
7371        GrantUri grantUri = new GrantUri(userId, uri, false);
7372        synchronized(this) {
7373            final ProcessRecord r = getRecordForAppLocked(caller);
7374            if (r == null) {
7375                throw new SecurityException("Unable to find app for caller "
7376                        + caller
7377                        + " when granting permission to uri " + grantUri);
7378            }
7379            if (targetPkg == null) {
7380                throw new IllegalArgumentException("null target");
7381            }
7382            if (grantUri == null) {
7383                throw new IllegalArgumentException("null uri");
7384            }
7385
7386            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7387                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7388                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7389                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7390
7391            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7392                    UserHandle.getUserId(r.uid));
7393        }
7394    }
7395
7396    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7397        if (perm.modeFlags == 0) {
7398            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7399                    perm.targetUid);
7400            if (perms != null) {
7401                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7402                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7403
7404                perms.remove(perm.uri);
7405                if (perms.isEmpty()) {
7406                    mGrantedUriPermissions.remove(perm.targetUid);
7407                }
7408            }
7409        }
7410    }
7411
7412    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7413        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7414
7415        final IPackageManager pm = AppGlobals.getPackageManager();
7416        final String authority = grantUri.uri.getAuthority();
7417        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7418        if (pi == null) {
7419            Slog.w(TAG, "No content provider found for permission revoke: "
7420                    + grantUri.toSafeString());
7421            return;
7422        }
7423
7424        // Does the caller have this permission on the URI?
7425        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7426            // If they don't have direct access to the URI, then revoke any
7427            // ownerless URI permissions that have been granted to them.
7428            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7429            if (perms != null) {
7430                boolean persistChanged = false;
7431                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7432                    final UriPermission perm = it.next();
7433                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7434                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7435                        if (DEBUG_URI_PERMISSION)
7436                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7437                                    " permission to " + perm.uri);
7438                        persistChanged |= perm.revokeModes(
7439                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7440                        if (perm.modeFlags == 0) {
7441                            it.remove();
7442                        }
7443                    }
7444                }
7445                if (perms.isEmpty()) {
7446                    mGrantedUriPermissions.remove(callingUid);
7447                }
7448                if (persistChanged) {
7449                    schedulePersistUriGrants();
7450                }
7451            }
7452            return;
7453        }
7454
7455        boolean persistChanged = false;
7456
7457        // Go through all of the permissions and remove any that match.
7458        int N = mGrantedUriPermissions.size();
7459        for (int i = 0; i < N; i++) {
7460            final int targetUid = mGrantedUriPermissions.keyAt(i);
7461            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7462
7463            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7464                final UriPermission perm = it.next();
7465                if (perm.uri.sourceUserId == grantUri.sourceUserId
7466                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7467                    if (DEBUG_URI_PERMISSION)
7468                        Slog.v(TAG,
7469                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7470                    persistChanged |= perm.revokeModes(
7471                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7472                    if (perm.modeFlags == 0) {
7473                        it.remove();
7474                    }
7475                }
7476            }
7477
7478            if (perms.isEmpty()) {
7479                mGrantedUriPermissions.remove(targetUid);
7480                N--;
7481                i--;
7482            }
7483        }
7484
7485        if (persistChanged) {
7486            schedulePersistUriGrants();
7487        }
7488    }
7489
7490    /**
7491     * @param uri This uri must NOT contain an embedded userId.
7492     * @param userId The userId in which the uri is to be resolved.
7493     */
7494    @Override
7495    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7496            int userId) {
7497        enforceNotIsolatedCaller("revokeUriPermission");
7498        synchronized(this) {
7499            final ProcessRecord r = getRecordForAppLocked(caller);
7500            if (r == null) {
7501                throw new SecurityException("Unable to find app for caller "
7502                        + caller
7503                        + " when revoking permission to uri " + uri);
7504            }
7505            if (uri == null) {
7506                Slog.w(TAG, "revokeUriPermission: null uri");
7507                return;
7508            }
7509
7510            if (!Intent.isAccessUriMode(modeFlags)) {
7511                return;
7512            }
7513
7514            final IPackageManager pm = AppGlobals.getPackageManager();
7515            final String authority = uri.getAuthority();
7516            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7517            if (pi == null) {
7518                Slog.w(TAG, "No content provider found for permission revoke: "
7519                        + uri.toSafeString());
7520                return;
7521            }
7522
7523            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7524        }
7525    }
7526
7527    /**
7528     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7529     * given package.
7530     *
7531     * @param packageName Package name to match, or {@code null} to apply to all
7532     *            packages.
7533     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7534     *            to all users.
7535     * @param persistable If persistable grants should be removed.
7536     */
7537    private void removeUriPermissionsForPackageLocked(
7538            String packageName, int userHandle, boolean persistable) {
7539        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7540            throw new IllegalArgumentException("Must narrow by either package or user");
7541        }
7542
7543        boolean persistChanged = false;
7544
7545        int N = mGrantedUriPermissions.size();
7546        for (int i = 0; i < N; i++) {
7547            final int targetUid = mGrantedUriPermissions.keyAt(i);
7548            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7549
7550            // Only inspect grants matching user
7551            if (userHandle == UserHandle.USER_ALL
7552                    || userHandle == UserHandle.getUserId(targetUid)) {
7553                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7554                    final UriPermission perm = it.next();
7555
7556                    // Only inspect grants matching package
7557                    if (packageName == null || perm.sourcePkg.equals(packageName)
7558                            || perm.targetPkg.equals(packageName)) {
7559                        persistChanged |= perm.revokeModes(persistable
7560                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7561
7562                        // Only remove when no modes remain; any persisted grants
7563                        // will keep this alive.
7564                        if (perm.modeFlags == 0) {
7565                            it.remove();
7566                        }
7567                    }
7568                }
7569
7570                if (perms.isEmpty()) {
7571                    mGrantedUriPermissions.remove(targetUid);
7572                    N--;
7573                    i--;
7574                }
7575            }
7576        }
7577
7578        if (persistChanged) {
7579            schedulePersistUriGrants();
7580        }
7581    }
7582
7583    @Override
7584    public IBinder newUriPermissionOwner(String name) {
7585        enforceNotIsolatedCaller("newUriPermissionOwner");
7586        synchronized(this) {
7587            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7588            return owner.getExternalTokenLocked();
7589        }
7590    }
7591
7592    /**
7593     * @param uri This uri must NOT contain an embedded userId.
7594     * @param sourceUserId The userId in which the uri is to be resolved.
7595     * @param targetUserId The userId of the app that receives the grant.
7596     */
7597    @Override
7598    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7599            final int modeFlags, int sourceUserId, int targetUserId) {
7600        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7601                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7602        synchronized(this) {
7603            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7604            if (owner == null) {
7605                throw new IllegalArgumentException("Unknown owner: " + token);
7606            }
7607            if (fromUid != Binder.getCallingUid()) {
7608                if (Binder.getCallingUid() != Process.myUid()) {
7609                    // Only system code can grant URI permissions on behalf
7610                    // of other users.
7611                    throw new SecurityException("nice try");
7612                }
7613            }
7614            if (targetPkg == null) {
7615                throw new IllegalArgumentException("null target");
7616            }
7617            if (uri == null) {
7618                throw new IllegalArgumentException("null uri");
7619            }
7620
7621            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7622                    modeFlags, owner, targetUserId);
7623        }
7624    }
7625
7626    /**
7627     * @param uri This uri must NOT contain an embedded userId.
7628     * @param userId The userId in which the uri is to be resolved.
7629     */
7630    @Override
7631    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7632        synchronized(this) {
7633            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7634            if (owner == null) {
7635                throw new IllegalArgumentException("Unknown owner: " + token);
7636            }
7637
7638            if (uri == null) {
7639                owner.removeUriPermissionsLocked(mode);
7640            } else {
7641                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7642            }
7643        }
7644    }
7645
7646    private void schedulePersistUriGrants() {
7647        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7648            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7649                    10 * DateUtils.SECOND_IN_MILLIS);
7650        }
7651    }
7652
7653    private void writeGrantedUriPermissions() {
7654        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7655
7656        // Snapshot permissions so we can persist without lock
7657        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7658        synchronized (this) {
7659            final int size = mGrantedUriPermissions.size();
7660            for (int i = 0; i < size; i++) {
7661                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7662                for (UriPermission perm : perms.values()) {
7663                    if (perm.persistedModeFlags != 0) {
7664                        persist.add(perm.snapshot());
7665                    }
7666                }
7667            }
7668        }
7669
7670        FileOutputStream fos = null;
7671        try {
7672            fos = mGrantFile.startWrite();
7673
7674            XmlSerializer out = new FastXmlSerializer();
7675            out.setOutput(fos, "utf-8");
7676            out.startDocument(null, true);
7677            out.startTag(null, TAG_URI_GRANTS);
7678            for (UriPermission.Snapshot perm : persist) {
7679                out.startTag(null, TAG_URI_GRANT);
7680                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7681                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7682                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7683                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7684                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7685                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7686                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7687                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7688                out.endTag(null, TAG_URI_GRANT);
7689            }
7690            out.endTag(null, TAG_URI_GRANTS);
7691            out.endDocument();
7692
7693            mGrantFile.finishWrite(fos);
7694        } catch (IOException e) {
7695            if (fos != null) {
7696                mGrantFile.failWrite(fos);
7697            }
7698        }
7699    }
7700
7701    private void readGrantedUriPermissionsLocked() {
7702        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7703
7704        final long now = System.currentTimeMillis();
7705
7706        FileInputStream fis = null;
7707        try {
7708            fis = mGrantFile.openRead();
7709            final XmlPullParser in = Xml.newPullParser();
7710            in.setInput(fis, null);
7711
7712            int type;
7713            while ((type = in.next()) != END_DOCUMENT) {
7714                final String tag = in.getName();
7715                if (type == START_TAG) {
7716                    if (TAG_URI_GRANT.equals(tag)) {
7717                        final int sourceUserId;
7718                        final int targetUserId;
7719                        final int userHandle = readIntAttribute(in,
7720                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7721                        if (userHandle != UserHandle.USER_NULL) {
7722                            // For backwards compatibility.
7723                            sourceUserId = userHandle;
7724                            targetUserId = userHandle;
7725                        } else {
7726                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7727                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7728                        }
7729                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7730                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7731                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7732                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7733                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7734                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7735
7736                        // Sanity check that provider still belongs to source package
7737                        final ProviderInfo pi = getProviderInfoLocked(
7738                                uri.getAuthority(), sourceUserId);
7739                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7740                            int targetUid = -1;
7741                            try {
7742                                targetUid = AppGlobals.getPackageManager()
7743                                        .getPackageUid(targetPkg, targetUserId);
7744                            } catch (RemoteException e) {
7745                            }
7746                            if (targetUid != -1) {
7747                                final UriPermission perm = findOrCreateUriPermissionLocked(
7748                                        sourcePkg, targetPkg, targetUid,
7749                                        new GrantUri(sourceUserId, uri, prefix));
7750                                perm.initPersistedModes(modeFlags, createdTime);
7751                            }
7752                        } else {
7753                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7754                                    + " but instead found " + pi);
7755                        }
7756                    }
7757                }
7758            }
7759        } catch (FileNotFoundException e) {
7760            // Missing grants is okay
7761        } catch (IOException e) {
7762            Slog.wtf(TAG, "Failed reading Uri grants", e);
7763        } catch (XmlPullParserException e) {
7764            Slog.wtf(TAG, "Failed reading Uri grants", e);
7765        } finally {
7766            IoUtils.closeQuietly(fis);
7767        }
7768    }
7769
7770    /**
7771     * @param uri This uri must NOT contain an embedded userId.
7772     * @param userId The userId in which the uri is to be resolved.
7773     */
7774    @Override
7775    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7776        enforceNotIsolatedCaller("takePersistableUriPermission");
7777
7778        Preconditions.checkFlagsArgument(modeFlags,
7779                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7780
7781        synchronized (this) {
7782            final int callingUid = Binder.getCallingUid();
7783            boolean persistChanged = false;
7784            GrantUri grantUri = new GrantUri(userId, uri, false);
7785
7786            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7787                    new GrantUri(userId, uri, false));
7788            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7789                    new GrantUri(userId, uri, true));
7790
7791            final boolean exactValid = (exactPerm != null)
7792                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7793            final boolean prefixValid = (prefixPerm != null)
7794                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7795
7796            if (!(exactValid || prefixValid)) {
7797                throw new SecurityException("No persistable permission grants found for UID "
7798                        + callingUid + " and Uri " + grantUri.toSafeString());
7799            }
7800
7801            if (exactValid) {
7802                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7803            }
7804            if (prefixValid) {
7805                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7806            }
7807
7808            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7809
7810            if (persistChanged) {
7811                schedulePersistUriGrants();
7812            }
7813        }
7814    }
7815
7816    /**
7817     * @param uri This uri must NOT contain an embedded userId.
7818     * @param userId The userId in which the uri is to be resolved.
7819     */
7820    @Override
7821    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7822        enforceNotIsolatedCaller("releasePersistableUriPermission");
7823
7824        Preconditions.checkFlagsArgument(modeFlags,
7825                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7826
7827        synchronized (this) {
7828            final int callingUid = Binder.getCallingUid();
7829            boolean persistChanged = false;
7830
7831            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7832                    new GrantUri(userId, uri, false));
7833            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7834                    new GrantUri(userId, uri, true));
7835            if (exactPerm == null && prefixPerm == null) {
7836                throw new SecurityException("No permission grants found for UID " + callingUid
7837                        + " and Uri " + uri.toSafeString());
7838            }
7839
7840            if (exactPerm != null) {
7841                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7842                removeUriPermissionIfNeededLocked(exactPerm);
7843            }
7844            if (prefixPerm != null) {
7845                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7846                removeUriPermissionIfNeededLocked(prefixPerm);
7847            }
7848
7849            if (persistChanged) {
7850                schedulePersistUriGrants();
7851            }
7852        }
7853    }
7854
7855    /**
7856     * Prune any older {@link UriPermission} for the given UID until outstanding
7857     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7858     *
7859     * @return if any mutations occured that require persisting.
7860     */
7861    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7862        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7863        if (perms == null) return false;
7864        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7865
7866        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7867        for (UriPermission perm : perms.values()) {
7868            if (perm.persistedModeFlags != 0) {
7869                persisted.add(perm);
7870            }
7871        }
7872
7873        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7874        if (trimCount <= 0) return false;
7875
7876        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7877        for (int i = 0; i < trimCount; i++) {
7878            final UriPermission perm = persisted.get(i);
7879
7880            if (DEBUG_URI_PERMISSION) {
7881                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7882            }
7883
7884            perm.releasePersistableModes(~0);
7885            removeUriPermissionIfNeededLocked(perm);
7886        }
7887
7888        return true;
7889    }
7890
7891    @Override
7892    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7893            String packageName, boolean incoming) {
7894        enforceNotIsolatedCaller("getPersistedUriPermissions");
7895        Preconditions.checkNotNull(packageName, "packageName");
7896
7897        final int callingUid = Binder.getCallingUid();
7898        final IPackageManager pm = AppGlobals.getPackageManager();
7899        try {
7900            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7901            if (packageUid != callingUid) {
7902                throw new SecurityException(
7903                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7904            }
7905        } catch (RemoteException e) {
7906            throw new SecurityException("Failed to verify package name ownership");
7907        }
7908
7909        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7910        synchronized (this) {
7911            if (incoming) {
7912                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7913                        callingUid);
7914                if (perms == null) {
7915                    Slog.w(TAG, "No permission grants found for " + packageName);
7916                } else {
7917                    for (UriPermission perm : perms.values()) {
7918                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7919                            result.add(perm.buildPersistedPublicApiObject());
7920                        }
7921                    }
7922                }
7923            } else {
7924                final int size = mGrantedUriPermissions.size();
7925                for (int i = 0; i < size; i++) {
7926                    final ArrayMap<GrantUri, UriPermission> perms =
7927                            mGrantedUriPermissions.valueAt(i);
7928                    for (UriPermission perm : perms.values()) {
7929                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7930                            result.add(perm.buildPersistedPublicApiObject());
7931                        }
7932                    }
7933                }
7934            }
7935        }
7936        return new ParceledListSlice<android.content.UriPermission>(result);
7937    }
7938
7939    @Override
7940    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7941        synchronized (this) {
7942            ProcessRecord app =
7943                who != null ? getRecordForAppLocked(who) : null;
7944            if (app == null) return;
7945
7946            Message msg = Message.obtain();
7947            msg.what = WAIT_FOR_DEBUGGER_MSG;
7948            msg.obj = app;
7949            msg.arg1 = waiting ? 1 : 0;
7950            mHandler.sendMessage(msg);
7951        }
7952    }
7953
7954    @Override
7955    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7956        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7957        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7958        outInfo.availMem = Process.getFreeMemory();
7959        outInfo.totalMem = Process.getTotalMemory();
7960        outInfo.threshold = homeAppMem;
7961        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7962        outInfo.hiddenAppThreshold = cachedAppMem;
7963        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7964                ProcessList.SERVICE_ADJ);
7965        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7966                ProcessList.VISIBLE_APP_ADJ);
7967        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7968                ProcessList.FOREGROUND_APP_ADJ);
7969    }
7970
7971    // =========================================================
7972    // TASK MANAGEMENT
7973    // =========================================================
7974
7975    @Override
7976    public List<IAppTask> getAppTasks(String callingPackage) {
7977        int callingUid = Binder.getCallingUid();
7978        long ident = Binder.clearCallingIdentity();
7979
7980        synchronized(this) {
7981            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7982            try {
7983                if (localLOGV) Slog.v(TAG, "getAppTasks");
7984
7985                final int N = mRecentTasks.size();
7986                for (int i = 0; i < N; i++) {
7987                    TaskRecord tr = mRecentTasks.get(i);
7988                    // Skip tasks that do not match the caller.  We don't need to verify
7989                    // callingPackage, because we are also limiting to callingUid and know
7990                    // that will limit to the correct security sandbox.
7991                    if (tr.effectiveUid != callingUid) {
7992                        continue;
7993                    }
7994                    Intent intent = tr.getBaseIntent();
7995                    if (intent == null ||
7996                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7997                        continue;
7998                    }
7999                    ActivityManager.RecentTaskInfo taskInfo =
8000                            createRecentTaskInfoFromTaskRecord(tr);
8001                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8002                    list.add(taskImpl);
8003                }
8004            } finally {
8005                Binder.restoreCallingIdentity(ident);
8006            }
8007            return list;
8008        }
8009    }
8010
8011    @Override
8012    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8013        final int callingUid = Binder.getCallingUid();
8014        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8015
8016        synchronized(this) {
8017            if (localLOGV) Slog.v(
8018                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8019
8020            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8021                    callingUid);
8022
8023            // TODO: Improve with MRU list from all ActivityStacks.
8024            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8025        }
8026
8027        return list;
8028    }
8029
8030    /**
8031     * Creates a new RecentTaskInfo from a TaskRecord.
8032     */
8033    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8034        // Update the task description to reflect any changes in the task stack
8035        tr.updateTaskDescription();
8036
8037        // Compose the recent task info
8038        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8039        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8040        rti.persistentId = tr.taskId;
8041        rti.baseIntent = new Intent(tr.getBaseIntent());
8042        rti.origActivity = tr.origActivity;
8043        rti.description = tr.lastDescription;
8044        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8045        rti.userId = tr.userId;
8046        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8047        rti.firstActiveTime = tr.firstActiveTime;
8048        rti.lastActiveTime = tr.lastActiveTime;
8049        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8050        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8051        return rti;
8052    }
8053
8054    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8055        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8056                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8057        if (!allowed) {
8058            if (checkPermission(android.Manifest.permission.GET_TASKS,
8059                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8060                // Temporary compatibility: some existing apps on the system image may
8061                // still be requesting the old permission and not switched to the new
8062                // one; if so, we'll still allow them full access.  This means we need
8063                // to see if they are holding the old permission and are a system app.
8064                try {
8065                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8066                        allowed = true;
8067                        Slog.w(TAG, caller + ": caller " + callingUid
8068                                + " is using old GET_TASKS but privileged; allowing");
8069                    }
8070                } catch (RemoteException e) {
8071                }
8072            }
8073        }
8074        if (!allowed) {
8075            Slog.w(TAG, caller + ": caller " + callingUid
8076                    + " does not hold GET_TASKS; limiting output");
8077        }
8078        return allowed;
8079    }
8080
8081    @Override
8082    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8083        final int callingUid = Binder.getCallingUid();
8084        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8085                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8086
8087        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8088        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8089        synchronized (this) {
8090            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8091                    callingUid);
8092            final boolean detailed = checkCallingPermission(
8093                    android.Manifest.permission.GET_DETAILED_TASKS)
8094                    == PackageManager.PERMISSION_GRANTED;
8095
8096            final int N = mRecentTasks.size();
8097            ArrayList<ActivityManager.RecentTaskInfo> res
8098                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8099                            maxNum < N ? maxNum : N);
8100
8101            final Set<Integer> includedUsers;
8102            if (includeProfiles) {
8103                includedUsers = getProfileIdsLocked(userId);
8104            } else {
8105                includedUsers = new HashSet<Integer>();
8106            }
8107            includedUsers.add(Integer.valueOf(userId));
8108
8109            for (int i=0; i<N && maxNum > 0; i++) {
8110                TaskRecord tr = mRecentTasks.get(i);
8111                // Only add calling user or related users recent tasks
8112                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8113                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8114                    continue;
8115                }
8116
8117                // Return the entry if desired by the caller.  We always return
8118                // the first entry, because callers always expect this to be the
8119                // foreground app.  We may filter others if the caller has
8120                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8121                // we should exclude the entry.
8122
8123                if (i == 0
8124                        || withExcluded
8125                        || (tr.intent == null)
8126                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8127                                == 0)) {
8128                    if (!allowed) {
8129                        // If the caller doesn't have the GET_TASKS permission, then only
8130                        // allow them to see a small subset of tasks -- their own and home.
8131                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8132                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8133                            continue;
8134                        }
8135                    }
8136                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8137                        if (tr.stack != null && tr.stack.isHomeStack()) {
8138                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8139                            continue;
8140                        }
8141                    }
8142                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8143                        // Don't include auto remove tasks that are finished or finishing.
8144                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8145                                + tr);
8146                        continue;
8147                    }
8148                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8149                            && !tr.isAvailable) {
8150                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8151                        continue;
8152                    }
8153
8154                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8155                    if (!detailed) {
8156                        rti.baseIntent.replaceExtras((Bundle)null);
8157                    }
8158
8159                    res.add(rti);
8160                    maxNum--;
8161                }
8162            }
8163            return res;
8164        }
8165    }
8166
8167    private TaskRecord taskForIdLocked(int id) {
8168        final TaskRecord task = recentTaskForIdLocked(id);
8169        if (task != null) {
8170            return task;
8171        }
8172
8173        // Don't give up. Sometimes it just hasn't made it to recents yet.
8174        return mStackSupervisor.anyTaskForIdLocked(id);
8175    }
8176
8177    private TaskRecord recentTaskForIdLocked(int id) {
8178        final int N = mRecentTasks.size();
8179            for (int i=0; i<N; i++) {
8180                TaskRecord tr = mRecentTasks.get(i);
8181                if (tr.taskId == id) {
8182                    return tr;
8183                }
8184            }
8185            return null;
8186    }
8187
8188    @Override
8189    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8190        synchronized (this) {
8191            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8192                    "getTaskThumbnail()");
8193            TaskRecord tr = recentTaskForIdLocked(id);
8194            if (tr != null) {
8195                return tr.getTaskThumbnailLocked();
8196            }
8197        }
8198        return null;
8199    }
8200
8201    @Override
8202    public int addAppTask(IBinder activityToken, Intent intent,
8203            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8204        final int callingUid = Binder.getCallingUid();
8205        final long callingIdent = Binder.clearCallingIdentity();
8206
8207        try {
8208            synchronized (this) {
8209                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8210                if (r == null) {
8211                    throw new IllegalArgumentException("Activity does not exist; token="
8212                            + activityToken);
8213                }
8214                ComponentName comp = intent.getComponent();
8215                if (comp == null) {
8216                    throw new IllegalArgumentException("Intent " + intent
8217                            + " must specify explicit component");
8218                }
8219                if (thumbnail.getWidth() != mThumbnailWidth
8220                        || thumbnail.getHeight() != mThumbnailHeight) {
8221                    throw new IllegalArgumentException("Bad thumbnail size: got "
8222                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8223                            + mThumbnailWidth + "x" + mThumbnailHeight);
8224                }
8225                if (intent.getSelector() != null) {
8226                    intent.setSelector(null);
8227                }
8228                if (intent.getSourceBounds() != null) {
8229                    intent.setSourceBounds(null);
8230                }
8231                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8232                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8233                        // The caller has added this as an auto-remove task...  that makes no
8234                        // sense, so turn off auto-remove.
8235                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8236                    }
8237                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8238                    // Must be a new task.
8239                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8240                }
8241                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8242                    mLastAddedTaskActivity = null;
8243                }
8244                ActivityInfo ainfo = mLastAddedTaskActivity;
8245                if (ainfo == null) {
8246                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8247                            comp, 0, UserHandle.getUserId(callingUid));
8248                    if (ainfo.applicationInfo.uid != callingUid) {
8249                        throw new SecurityException(
8250                                "Can't add task for another application: target uid="
8251                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8252                    }
8253                }
8254
8255                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8256                        intent, description);
8257
8258                int trimIdx = trimRecentsForTaskLocked(task, false);
8259                if (trimIdx >= 0) {
8260                    // If this would have caused a trim, then we'll abort because that
8261                    // means it would be added at the end of the list but then just removed.
8262                    return -1;
8263                }
8264
8265                final int N = mRecentTasks.size();
8266                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8267                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8268                    tr.removedFromRecents();
8269                }
8270
8271                task.inRecents = true;
8272                mRecentTasks.add(task);
8273                r.task.stack.addTask(task, false, false);
8274
8275                task.setLastThumbnail(thumbnail);
8276                task.freeLastThumbnail();
8277
8278                return task.taskId;
8279            }
8280        } finally {
8281            Binder.restoreCallingIdentity(callingIdent);
8282        }
8283    }
8284
8285    @Override
8286    public Point getAppTaskThumbnailSize() {
8287        synchronized (this) {
8288            return new Point(mThumbnailWidth,  mThumbnailHeight);
8289        }
8290    }
8291
8292    @Override
8293    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8294        synchronized (this) {
8295            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8296            if (r != null) {
8297                r.setTaskDescription(td);
8298                r.task.updateTaskDescription();
8299            }
8300        }
8301    }
8302
8303    @Override
8304    public Bitmap getTaskDescriptionIcon(String filename) {
8305        if (!FileUtils.isValidExtFilename(filename)
8306                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8307            throw new IllegalArgumentException("Bad filename: " + filename);
8308        }
8309        return mTaskPersister.getTaskDescriptionIcon(filename);
8310    }
8311
8312    @Override
8313    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8314            throws RemoteException {
8315        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8316                opts.getCustomInPlaceResId() == 0) {
8317            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8318                    "with valid animation");
8319        }
8320        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8321        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8322                opts.getCustomInPlaceResId());
8323        mWindowManager.executeAppTransition();
8324    }
8325
8326    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8327        mRecentTasks.remove(tr);
8328        tr.removedFromRecents();
8329        ComponentName component = tr.getBaseIntent().getComponent();
8330        if (component == null) {
8331            Slog.w(TAG, "No component for base intent of task: " + tr);
8332            return;
8333        }
8334
8335        if (!killProcess) {
8336            return;
8337        }
8338
8339        // Determine if the process(es) for this task should be killed.
8340        final String pkg = component.getPackageName();
8341        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8342        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8343        for (int i = 0; i < pmap.size(); i++) {
8344
8345            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8346            for (int j = 0; j < uids.size(); j++) {
8347                ProcessRecord proc = uids.valueAt(j);
8348                if (proc.userId != tr.userId) {
8349                    // Don't kill process for a different user.
8350                    continue;
8351                }
8352                if (proc == mHomeProcess) {
8353                    // Don't kill the home process along with tasks from the same package.
8354                    continue;
8355                }
8356                if (!proc.pkgList.containsKey(pkg)) {
8357                    // Don't kill process that is not associated with this task.
8358                    continue;
8359                }
8360
8361                for (int k = 0; k < proc.activities.size(); k++) {
8362                    TaskRecord otherTask = proc.activities.get(k).task;
8363                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8364                        // Don't kill process(es) that has an activity in a different task that is
8365                        // also in recents.
8366                        return;
8367                    }
8368                }
8369
8370                // Add process to kill list.
8371                procsToKill.add(proc);
8372            }
8373        }
8374
8375        // Find any running services associated with this app and stop if needed.
8376        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8377
8378        // Kill the running processes.
8379        for (int i = 0; i < procsToKill.size(); i++) {
8380            ProcessRecord pr = procsToKill.get(i);
8381            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8382                pr.kill("remove task", true);
8383            } else {
8384                pr.waitingToKill = "remove task";
8385            }
8386        }
8387    }
8388
8389    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8390        // Remove all tasks with activities in the specified package from the list of recent tasks
8391        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8392            TaskRecord tr = mRecentTasks.get(i);
8393            if (tr.userId != userId) continue;
8394
8395            ComponentName cn = tr.intent.getComponent();
8396            if (cn != null && cn.getPackageName().equals(packageName)) {
8397                // If the package name matches, remove the task.
8398                removeTaskByIdLocked(tr.taskId, true);
8399            }
8400        }
8401    }
8402
8403    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8404        final IPackageManager pm = AppGlobals.getPackageManager();
8405        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8406
8407        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8408            TaskRecord tr = mRecentTasks.get(i);
8409            if (tr.userId != userId) continue;
8410
8411            ComponentName cn = tr.intent.getComponent();
8412            if (cn != null && cn.getPackageName().equals(packageName)) {
8413                // Skip if component still exists in the package.
8414                if (componentsKnownToExist.contains(cn)) continue;
8415
8416                try {
8417                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8418                    if (info != null) {
8419                        componentsKnownToExist.add(cn);
8420                    } else {
8421                        removeTaskByIdLocked(tr.taskId, false);
8422                    }
8423                } catch (RemoteException e) {
8424                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8425                }
8426            }
8427        }
8428    }
8429
8430    /**
8431     * Removes the task with the specified task id.
8432     *
8433     * @param taskId Identifier of the task to be removed.
8434     * @param killProcess Kill any process associated with the task if possible.
8435     * @return Returns true if the given task was found and removed.
8436     */
8437    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8438        TaskRecord tr = taskForIdLocked(taskId);
8439        if (tr != null) {
8440            tr.removeTaskActivitiesLocked();
8441            cleanUpRemovedTaskLocked(tr, killProcess);
8442            if (tr.isPersistable) {
8443                notifyTaskPersisterLocked(null, true);
8444            }
8445            return true;
8446        }
8447        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8448        return false;
8449    }
8450
8451    @Override
8452    public boolean removeTask(int taskId) {
8453        synchronized (this) {
8454            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8455                    "removeTask()");
8456            long ident = Binder.clearCallingIdentity();
8457            try {
8458                return removeTaskByIdLocked(taskId, true);
8459            } finally {
8460                Binder.restoreCallingIdentity(ident);
8461            }
8462        }
8463    }
8464
8465    /**
8466     * TODO: Add mController hook
8467     */
8468    @Override
8469    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8470        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8471                "moveTaskToFront()");
8472
8473        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8474        synchronized(this) {
8475            moveTaskToFrontLocked(taskId, flags, options);
8476        }
8477    }
8478
8479    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8480        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8481                Binder.getCallingUid(), -1, -1, "Task to front")) {
8482            ActivityOptions.abort(options);
8483            return;
8484        }
8485        final long origId = Binder.clearCallingIdentity();
8486        try {
8487            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8488            if (task == null) {
8489                Slog.d(TAG, "Could not find task for id: "+ taskId);
8490                return;
8491            }
8492            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8493                mStackSupervisor.showLockTaskToast();
8494                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8495                return;
8496            }
8497            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8498            if (prev != null && prev.isRecentsActivity()) {
8499                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8500            }
8501            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8502        } finally {
8503            Binder.restoreCallingIdentity(origId);
8504        }
8505        ActivityOptions.abort(options);
8506    }
8507
8508    @Override
8509    public void moveTaskToBack(int taskId) {
8510        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8511                "moveTaskToBack()");
8512
8513        synchronized(this) {
8514            TaskRecord tr = taskForIdLocked(taskId);
8515            if (tr != null) {
8516                if (tr == mStackSupervisor.mLockTaskModeTask) {
8517                    mStackSupervisor.showLockTaskToast();
8518                    return;
8519                }
8520                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8521                ActivityStack stack = tr.stack;
8522                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8523                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8524                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8525                        return;
8526                    }
8527                }
8528                final long origId = Binder.clearCallingIdentity();
8529                try {
8530                    stack.moveTaskToBackLocked(taskId, null);
8531                } finally {
8532                    Binder.restoreCallingIdentity(origId);
8533                }
8534            }
8535        }
8536    }
8537
8538    /**
8539     * Moves an activity, and all of the other activities within the same task, to the bottom
8540     * of the history stack.  The activity's order within the task is unchanged.
8541     *
8542     * @param token A reference to the activity we wish to move
8543     * @param nonRoot If false then this only works if the activity is the root
8544     *                of a task; if true it will work for any activity in a task.
8545     * @return Returns true if the move completed, false if not.
8546     */
8547    @Override
8548    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8549        enforceNotIsolatedCaller("moveActivityTaskToBack");
8550        synchronized(this) {
8551            final long origId = Binder.clearCallingIdentity();
8552            try {
8553                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8554                if (taskId >= 0) {
8555                    if ((mStackSupervisor.mLockTaskModeTask != null)
8556                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8557                        mStackSupervisor.showLockTaskToast();
8558                        return false;
8559                    }
8560                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8561                }
8562            } finally {
8563                Binder.restoreCallingIdentity(origId);
8564            }
8565        }
8566        return false;
8567    }
8568
8569    @Override
8570    public void moveTaskBackwards(int task) {
8571        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8572                "moveTaskBackwards()");
8573
8574        synchronized(this) {
8575            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8576                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8577                return;
8578            }
8579            final long origId = Binder.clearCallingIdentity();
8580            moveTaskBackwardsLocked(task);
8581            Binder.restoreCallingIdentity(origId);
8582        }
8583    }
8584
8585    private final void moveTaskBackwardsLocked(int task) {
8586        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8587    }
8588
8589    @Override
8590    public IBinder getHomeActivityToken() throws RemoteException {
8591        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8592                "getHomeActivityToken()");
8593        synchronized (this) {
8594            return mStackSupervisor.getHomeActivityToken();
8595        }
8596    }
8597
8598    @Override
8599    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8600            IActivityContainerCallback callback) throws RemoteException {
8601        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8602                "createActivityContainer()");
8603        synchronized (this) {
8604            if (parentActivityToken == null) {
8605                throw new IllegalArgumentException("parent token must not be null");
8606            }
8607            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8608            if (r == null) {
8609                return null;
8610            }
8611            if (callback == null) {
8612                throw new IllegalArgumentException("callback must not be null");
8613            }
8614            return mStackSupervisor.createActivityContainer(r, callback);
8615        }
8616    }
8617
8618    @Override
8619    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8620        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8621                "deleteActivityContainer()");
8622        synchronized (this) {
8623            mStackSupervisor.deleteActivityContainer(container);
8624        }
8625    }
8626
8627    @Override
8628    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8629            throws RemoteException {
8630        synchronized (this) {
8631            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8632            if (stack != null) {
8633                return stack.mActivityContainer;
8634            }
8635            return null;
8636        }
8637    }
8638
8639    @Override
8640    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8641        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8642                "moveTaskToStack()");
8643        if (stackId == HOME_STACK_ID) {
8644            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8645                    new RuntimeException("here").fillInStackTrace());
8646        }
8647        synchronized (this) {
8648            long ident = Binder.clearCallingIdentity();
8649            try {
8650                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8651                        + stackId + " toTop=" + toTop);
8652                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8653            } finally {
8654                Binder.restoreCallingIdentity(ident);
8655            }
8656        }
8657    }
8658
8659    @Override
8660    public void resizeStack(int stackBoxId, Rect bounds) {
8661        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8662                "resizeStackBox()");
8663        long ident = Binder.clearCallingIdentity();
8664        try {
8665            mWindowManager.resizeStack(stackBoxId, bounds);
8666        } finally {
8667            Binder.restoreCallingIdentity(ident);
8668        }
8669    }
8670
8671    @Override
8672    public List<StackInfo> getAllStackInfos() {
8673        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8674                "getAllStackInfos()");
8675        long ident = Binder.clearCallingIdentity();
8676        try {
8677            synchronized (this) {
8678                return mStackSupervisor.getAllStackInfosLocked();
8679            }
8680        } finally {
8681            Binder.restoreCallingIdentity(ident);
8682        }
8683    }
8684
8685    @Override
8686    public StackInfo getStackInfo(int stackId) {
8687        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8688                "getStackInfo()");
8689        long ident = Binder.clearCallingIdentity();
8690        try {
8691            synchronized (this) {
8692                return mStackSupervisor.getStackInfoLocked(stackId);
8693            }
8694        } finally {
8695            Binder.restoreCallingIdentity(ident);
8696        }
8697    }
8698
8699    @Override
8700    public boolean isInHomeStack(int taskId) {
8701        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8702                "getStackInfo()");
8703        long ident = Binder.clearCallingIdentity();
8704        try {
8705            synchronized (this) {
8706                TaskRecord tr = taskForIdLocked(taskId);
8707                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8708            }
8709        } finally {
8710            Binder.restoreCallingIdentity(ident);
8711        }
8712    }
8713
8714    @Override
8715    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8716        synchronized(this) {
8717            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8718        }
8719    }
8720
8721    private boolean isLockTaskAuthorized(String pkg) {
8722        final DevicePolicyManager dpm = (DevicePolicyManager)
8723                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8724        try {
8725            int uid = mContext.getPackageManager().getPackageUid(pkg,
8726                    Binder.getCallingUserHandle().getIdentifier());
8727            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8728        } catch (NameNotFoundException e) {
8729            return false;
8730        }
8731    }
8732
8733    void startLockTaskMode(TaskRecord task) {
8734        final String pkg;
8735        synchronized (this) {
8736            pkg = task.intent.getComponent().getPackageName();
8737        }
8738        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8739        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8740            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8741                    StatusBarManagerInternal.class);
8742            if (statusBarManager != null) {
8743                statusBarManager.showScreenPinningRequest();
8744            }
8745            return;
8746        }
8747        long ident = Binder.clearCallingIdentity();
8748        try {
8749            synchronized (this) {
8750                // Since we lost lock on task, make sure it is still there.
8751                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8752                if (task != null) {
8753                    if (!isSystemInitiated
8754                            && ((mStackSupervisor.getFocusedStack() == null)
8755                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8756                        throw new IllegalArgumentException("Invalid task, not in foreground");
8757                    }
8758                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8759                }
8760            }
8761        } finally {
8762            Binder.restoreCallingIdentity(ident);
8763        }
8764    }
8765
8766    @Override
8767    public void startLockTaskMode(int taskId) {
8768        final TaskRecord task;
8769        long ident = Binder.clearCallingIdentity();
8770        try {
8771            synchronized (this) {
8772                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8773            }
8774        } finally {
8775            Binder.restoreCallingIdentity(ident);
8776        }
8777        if (task != null) {
8778            startLockTaskMode(task);
8779        }
8780    }
8781
8782    @Override
8783    public void startLockTaskMode(IBinder token) {
8784        final TaskRecord task;
8785        long ident = Binder.clearCallingIdentity();
8786        try {
8787            synchronized (this) {
8788                final ActivityRecord r = ActivityRecord.forToken(token);
8789                if (r == null) {
8790                    return;
8791                }
8792                task = r.task;
8793            }
8794        } finally {
8795            Binder.restoreCallingIdentity(ident);
8796        }
8797        if (task != null) {
8798            startLockTaskMode(task);
8799        }
8800    }
8801
8802    @Override
8803    public void startLockTaskModeOnCurrent() throws RemoteException {
8804        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8805                "startLockTaskModeOnCurrent");
8806        long ident = Binder.clearCallingIdentity();
8807        try {
8808            ActivityRecord r = null;
8809            synchronized (this) {
8810                r = mStackSupervisor.topRunningActivityLocked();
8811            }
8812            startLockTaskMode(r.task);
8813        } finally {
8814            Binder.restoreCallingIdentity(ident);
8815        }
8816    }
8817
8818    @Override
8819    public void stopLockTaskMode() {
8820        // Verify that the user matches the package of the intent for the TaskRecord
8821        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8822        // and stopLockTaskMode.
8823        final int callingUid = Binder.getCallingUid();
8824        if (callingUid != Process.SYSTEM_UID) {
8825            try {
8826                String pkg =
8827                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8828                int uid = mContext.getPackageManager().getPackageUid(pkg,
8829                        Binder.getCallingUserHandle().getIdentifier());
8830                if (uid != callingUid) {
8831                    throw new SecurityException("Invalid uid, expected " + uid);
8832                }
8833            } catch (NameNotFoundException e) {
8834                Log.d(TAG, "stopLockTaskMode " + e);
8835                return;
8836            }
8837        }
8838        long ident = Binder.clearCallingIdentity();
8839        try {
8840            Log.d(TAG, "stopLockTaskMode");
8841            // Stop lock task
8842            synchronized (this) {
8843                mStackSupervisor.setLockTaskModeLocked(null, false);
8844            }
8845        } finally {
8846            Binder.restoreCallingIdentity(ident);
8847        }
8848    }
8849
8850    @Override
8851    public void stopLockTaskModeOnCurrent() throws RemoteException {
8852        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8853                "stopLockTaskModeOnCurrent");
8854        long ident = Binder.clearCallingIdentity();
8855        try {
8856            stopLockTaskMode();
8857        } finally {
8858            Binder.restoreCallingIdentity(ident);
8859        }
8860    }
8861
8862    @Override
8863    public boolean isInLockTaskMode() {
8864        synchronized (this) {
8865            return mStackSupervisor.isInLockTaskMode();
8866        }
8867    }
8868
8869    // =========================================================
8870    // CONTENT PROVIDERS
8871    // =========================================================
8872
8873    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8874        List<ProviderInfo> providers = null;
8875        try {
8876            providers = AppGlobals.getPackageManager().
8877                queryContentProviders(app.processName, app.uid,
8878                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8879        } catch (RemoteException ex) {
8880        }
8881        if (DEBUG_MU)
8882            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8883        int userId = app.userId;
8884        if (providers != null) {
8885            int N = providers.size();
8886            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8887            for (int i=0; i<N; i++) {
8888                ProviderInfo cpi =
8889                    (ProviderInfo)providers.get(i);
8890                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8891                        cpi.name, cpi.flags);
8892                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8893                    // This is a singleton provider, but a user besides the
8894                    // default user is asking to initialize a process it runs
8895                    // in...  well, no, it doesn't actually run in this process,
8896                    // it runs in the process of the default user.  Get rid of it.
8897                    providers.remove(i);
8898                    N--;
8899                    i--;
8900                    continue;
8901                }
8902
8903                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8904                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8905                if (cpr == null) {
8906                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8907                    mProviderMap.putProviderByClass(comp, cpr);
8908                }
8909                if (DEBUG_MU)
8910                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8911                app.pubProviders.put(cpi.name, cpr);
8912                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8913                    // Don't add this if it is a platform component that is marked
8914                    // to run in multiple processes, because this is actually
8915                    // part of the framework so doesn't make sense to track as a
8916                    // separate apk in the process.
8917                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8918                            mProcessStats);
8919                }
8920                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8921            }
8922        }
8923        return providers;
8924    }
8925
8926    /**
8927     * Check if {@link ProcessRecord} has a possible chance at accessing the
8928     * given {@link ProviderInfo}. Final permission checking is always done
8929     * in {@link ContentProvider}.
8930     */
8931    private final String checkContentProviderPermissionLocked(
8932            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8933        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8934        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8935        boolean checkedGrants = false;
8936        if (checkUser) {
8937            // Looking for cross-user grants before enforcing the typical cross-users permissions
8938            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8939            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8940                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8941                    return null;
8942                }
8943                checkedGrants = true;
8944            }
8945            userId = handleIncomingUser(callingPid, callingUid, userId,
8946                    false, ALLOW_NON_FULL,
8947                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8948            if (userId != tmpTargetUserId) {
8949                // When we actually went to determine the final targer user ID, this ended
8950                // up different than our initial check for the authority.  This is because
8951                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8952                // SELF.  So we need to re-check the grants again.
8953                checkedGrants = false;
8954            }
8955        }
8956        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8957                cpi.applicationInfo.uid, cpi.exported)
8958                == PackageManager.PERMISSION_GRANTED) {
8959            return null;
8960        }
8961        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8962                cpi.applicationInfo.uid, cpi.exported)
8963                == PackageManager.PERMISSION_GRANTED) {
8964            return null;
8965        }
8966
8967        PathPermission[] pps = cpi.pathPermissions;
8968        if (pps != null) {
8969            int i = pps.length;
8970            while (i > 0) {
8971                i--;
8972                PathPermission pp = pps[i];
8973                String pprperm = pp.getReadPermission();
8974                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8975                        cpi.applicationInfo.uid, cpi.exported)
8976                        == PackageManager.PERMISSION_GRANTED) {
8977                    return null;
8978                }
8979                String ppwperm = pp.getWritePermission();
8980                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8981                        cpi.applicationInfo.uid, cpi.exported)
8982                        == PackageManager.PERMISSION_GRANTED) {
8983                    return null;
8984                }
8985            }
8986        }
8987        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8988            return null;
8989        }
8990
8991        String msg;
8992        if (!cpi.exported) {
8993            msg = "Permission Denial: opening provider " + cpi.name
8994                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8995                    + ", uid=" + callingUid + ") that is not exported from uid "
8996                    + cpi.applicationInfo.uid;
8997        } else {
8998            msg = "Permission Denial: opening provider " + cpi.name
8999                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9000                    + ", uid=" + callingUid + ") requires "
9001                    + cpi.readPermission + " or " + cpi.writePermission;
9002        }
9003        Slog.w(TAG, msg);
9004        return msg;
9005    }
9006
9007    /**
9008     * Returns if the ContentProvider has granted a uri to callingUid
9009     */
9010    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9011        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9012        if (perms != null) {
9013            for (int i=perms.size()-1; i>=0; i--) {
9014                GrantUri grantUri = perms.keyAt(i);
9015                if (grantUri.sourceUserId == userId || !checkUser) {
9016                    if (matchesProvider(grantUri.uri, cpi)) {
9017                        return true;
9018                    }
9019                }
9020            }
9021        }
9022        return false;
9023    }
9024
9025    /**
9026     * Returns true if the uri authority is one of the authorities specified in the provider.
9027     */
9028    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9029        String uriAuth = uri.getAuthority();
9030        String cpiAuth = cpi.authority;
9031        if (cpiAuth.indexOf(';') == -1) {
9032            return cpiAuth.equals(uriAuth);
9033        }
9034        String[] cpiAuths = cpiAuth.split(";");
9035        int length = cpiAuths.length;
9036        for (int i = 0; i < length; i++) {
9037            if (cpiAuths[i].equals(uriAuth)) return true;
9038        }
9039        return false;
9040    }
9041
9042    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9043            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9044        if (r != null) {
9045            for (int i=0; i<r.conProviders.size(); i++) {
9046                ContentProviderConnection conn = r.conProviders.get(i);
9047                if (conn.provider == cpr) {
9048                    if (DEBUG_PROVIDER) Slog.v(TAG,
9049                            "Adding provider requested by "
9050                            + r.processName + " from process "
9051                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9052                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9053                    if (stable) {
9054                        conn.stableCount++;
9055                        conn.numStableIncs++;
9056                    } else {
9057                        conn.unstableCount++;
9058                        conn.numUnstableIncs++;
9059                    }
9060                    return conn;
9061                }
9062            }
9063            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9064            if (stable) {
9065                conn.stableCount = 1;
9066                conn.numStableIncs = 1;
9067            } else {
9068                conn.unstableCount = 1;
9069                conn.numUnstableIncs = 1;
9070            }
9071            cpr.connections.add(conn);
9072            r.conProviders.add(conn);
9073            return conn;
9074        }
9075        cpr.addExternalProcessHandleLocked(externalProcessToken);
9076        return null;
9077    }
9078
9079    boolean decProviderCountLocked(ContentProviderConnection conn,
9080            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9081        if (conn != null) {
9082            cpr = conn.provider;
9083            if (DEBUG_PROVIDER) Slog.v(TAG,
9084                    "Removing provider requested by "
9085                    + conn.client.processName + " from process "
9086                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9087                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9088            if (stable) {
9089                conn.stableCount--;
9090            } else {
9091                conn.unstableCount--;
9092            }
9093            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9094                cpr.connections.remove(conn);
9095                conn.client.conProviders.remove(conn);
9096                return true;
9097            }
9098            return false;
9099        }
9100        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9101        return false;
9102    }
9103
9104    private void checkTime(long startTime, String where) {
9105        long now = SystemClock.elapsedRealtime();
9106        if ((now-startTime) > 1000) {
9107            // If we are taking more than a second, log about it.
9108            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9109        }
9110    }
9111
9112    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9113            String name, IBinder token, boolean stable, int userId) {
9114        ContentProviderRecord cpr;
9115        ContentProviderConnection conn = null;
9116        ProviderInfo cpi = null;
9117
9118        synchronized(this) {
9119            long startTime = SystemClock.elapsedRealtime();
9120
9121            ProcessRecord r = null;
9122            if (caller != null) {
9123                r = getRecordForAppLocked(caller);
9124                if (r == null) {
9125                    throw new SecurityException(
9126                            "Unable to find app for caller " + caller
9127                          + " (pid=" + Binder.getCallingPid()
9128                          + ") when getting content provider " + name);
9129                }
9130            }
9131
9132            boolean checkCrossUser = true;
9133
9134            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9135
9136            // First check if this content provider has been published...
9137            cpr = mProviderMap.getProviderByName(name, userId);
9138            // If that didn't work, check if it exists for user 0 and then
9139            // verify that it's a singleton provider before using it.
9140            if (cpr == null && userId != UserHandle.USER_OWNER) {
9141                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9142                if (cpr != null) {
9143                    cpi = cpr.info;
9144                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9145                            cpi.name, cpi.flags)
9146                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9147                        userId = UserHandle.USER_OWNER;
9148                        checkCrossUser = false;
9149                    } else {
9150                        cpr = null;
9151                        cpi = null;
9152                    }
9153                }
9154            }
9155
9156            boolean providerRunning = cpr != null;
9157            if (providerRunning) {
9158                cpi = cpr.info;
9159                String msg;
9160                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9161                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9162                        != null) {
9163                    throw new SecurityException(msg);
9164                }
9165                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9166
9167                if (r != null && cpr.canRunHere(r)) {
9168                    // This provider has been published or is in the process
9169                    // of being published...  but it is also allowed to run
9170                    // in the caller's process, so don't make a connection
9171                    // and just let the caller instantiate its own instance.
9172                    ContentProviderHolder holder = cpr.newHolder(null);
9173                    // don't give caller the provider object, it needs
9174                    // to make its own.
9175                    holder.provider = null;
9176                    return holder;
9177                }
9178
9179                final long origId = Binder.clearCallingIdentity();
9180
9181                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9182
9183                // In this case the provider instance already exists, so we can
9184                // return it right away.
9185                conn = incProviderCountLocked(r, cpr, token, stable);
9186                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9187                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9188                        // If this is a perceptible app accessing the provider,
9189                        // make sure to count it as being accessed and thus
9190                        // back up on the LRU list.  This is good because
9191                        // content providers are often expensive to start.
9192                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9193                        updateLruProcessLocked(cpr.proc, false, null);
9194                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9195                    }
9196                }
9197
9198                if (cpr.proc != null) {
9199                    if (false) {
9200                        if (cpr.name.flattenToShortString().equals(
9201                                "com.android.providers.calendar/.CalendarProvider2")) {
9202                            Slog.v(TAG, "****************** KILLING "
9203                                + cpr.name.flattenToShortString());
9204                            Process.killProcess(cpr.proc.pid);
9205                        }
9206                    }
9207                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9208                    boolean success = updateOomAdjLocked(cpr.proc);
9209                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9210                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9211                    // NOTE: there is still a race here where a signal could be
9212                    // pending on the process even though we managed to update its
9213                    // adj level.  Not sure what to do about this, but at least
9214                    // the race is now smaller.
9215                    if (!success) {
9216                        // Uh oh...  it looks like the provider's process
9217                        // has been killed on us.  We need to wait for a new
9218                        // process to be started, and make sure its death
9219                        // doesn't kill our process.
9220                        Slog.i(TAG,
9221                                "Existing provider " + cpr.name.flattenToShortString()
9222                                + " is crashing; detaching " + r);
9223                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9224                        checkTime(startTime, "getContentProviderImpl: before appDied");
9225                        appDiedLocked(cpr.proc);
9226                        checkTime(startTime, "getContentProviderImpl: after appDied");
9227                        if (!lastRef) {
9228                            // This wasn't the last ref our process had on
9229                            // the provider...  we have now been killed, bail.
9230                            return null;
9231                        }
9232                        providerRunning = false;
9233                        conn = null;
9234                    }
9235                }
9236
9237                Binder.restoreCallingIdentity(origId);
9238            }
9239
9240            boolean singleton;
9241            if (!providerRunning) {
9242                try {
9243                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9244                    cpi = AppGlobals.getPackageManager().
9245                        resolveContentProvider(name,
9246                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9247                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9248                } catch (RemoteException ex) {
9249                }
9250                if (cpi == null) {
9251                    return null;
9252                }
9253                // If the provider is a singleton AND
9254                // (it's a call within the same user || the provider is a
9255                // privileged app)
9256                // Then allow connecting to the singleton provider
9257                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9258                        cpi.name, cpi.flags)
9259                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9260                if (singleton) {
9261                    userId = UserHandle.USER_OWNER;
9262                }
9263                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9264                checkTime(startTime, "getContentProviderImpl: got app info for user");
9265
9266                String msg;
9267                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9268                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9269                        != null) {
9270                    throw new SecurityException(msg);
9271                }
9272                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9273
9274                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9275                        && !cpi.processName.equals("system")) {
9276                    // If this content provider does not run in the system
9277                    // process, and the system is not yet ready to run other
9278                    // processes, then fail fast instead of hanging.
9279                    throw new IllegalArgumentException(
9280                            "Attempt to launch content provider before system ready");
9281                }
9282
9283                // Make sure that the user who owns this provider is running.  If not,
9284                // we don't want to allow it to run.
9285                if (!isUserRunningLocked(userId, false)) {
9286                    Slog.w(TAG, "Unable to launch app "
9287                            + cpi.applicationInfo.packageName + "/"
9288                            + cpi.applicationInfo.uid + " for provider "
9289                            + name + ": user " + userId + " is stopped");
9290                    return null;
9291                }
9292
9293                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9294                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9295                cpr = mProviderMap.getProviderByClass(comp, userId);
9296                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9297                final boolean firstClass = cpr == null;
9298                if (firstClass) {
9299                    final long ident = Binder.clearCallingIdentity();
9300                    try {
9301                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9302                        ApplicationInfo ai =
9303                            AppGlobals.getPackageManager().
9304                                getApplicationInfo(
9305                                        cpi.applicationInfo.packageName,
9306                                        STOCK_PM_FLAGS, userId);
9307                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9308                        if (ai == null) {
9309                            Slog.w(TAG, "No package info for content provider "
9310                                    + cpi.name);
9311                            return null;
9312                        }
9313                        ai = getAppInfoForUser(ai, userId);
9314                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9315                    } catch (RemoteException ex) {
9316                        // pm is in same process, this will never happen.
9317                    } finally {
9318                        Binder.restoreCallingIdentity(ident);
9319                    }
9320                }
9321
9322                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9323
9324                if (r != null && cpr.canRunHere(r)) {
9325                    // If this is a multiprocess provider, then just return its
9326                    // info and allow the caller to instantiate it.  Only do
9327                    // this if the provider is the same user as the caller's
9328                    // process, or can run as root (so can be in any process).
9329                    return cpr.newHolder(null);
9330                }
9331
9332                if (DEBUG_PROVIDER) {
9333                    RuntimeException e = new RuntimeException("here");
9334                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9335                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9336                }
9337
9338                // This is single process, and our app is now connecting to it.
9339                // See if we are already in the process of launching this
9340                // provider.
9341                final int N = mLaunchingProviders.size();
9342                int i;
9343                for (i=0; i<N; i++) {
9344                    if (mLaunchingProviders.get(i) == cpr) {
9345                        break;
9346                    }
9347                }
9348
9349                // If the provider is not already being launched, then get it
9350                // started.
9351                if (i >= N) {
9352                    final long origId = Binder.clearCallingIdentity();
9353
9354                    try {
9355                        // Content provider is now in use, its package can't be stopped.
9356                        try {
9357                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9358                            AppGlobals.getPackageManager().setPackageStoppedState(
9359                                    cpr.appInfo.packageName, false, userId);
9360                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9361                        } catch (RemoteException e) {
9362                        } catch (IllegalArgumentException e) {
9363                            Slog.w(TAG, "Failed trying to unstop package "
9364                                    + cpr.appInfo.packageName + ": " + e);
9365                        }
9366
9367                        // Use existing process if already started
9368                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9369                        ProcessRecord proc = getProcessRecordLocked(
9370                                cpi.processName, cpr.appInfo.uid, false);
9371                        if (proc != null && proc.thread != null) {
9372                            if (DEBUG_PROVIDER) {
9373                                Slog.d(TAG, "Installing in existing process " + proc);
9374                            }
9375                            if (!proc.pubProviders.containsKey(cpi.name)) {
9376                                checkTime(startTime, "getContentProviderImpl: scheduling install");
9377                                proc.pubProviders.put(cpi.name, cpr);
9378                                try {
9379                                    proc.thread.scheduleInstallProvider(cpi);
9380                                } catch (RemoteException e) {
9381                                }
9382                            }
9383                        } else {
9384                            checkTime(startTime, "getContentProviderImpl: before start process");
9385                            proc = startProcessLocked(cpi.processName,
9386                                    cpr.appInfo, false, 0, "content provider",
9387                                    new ComponentName(cpi.applicationInfo.packageName,
9388                                            cpi.name), false, false, false);
9389                            checkTime(startTime, "getContentProviderImpl: after start process");
9390                            if (proc == null) {
9391                                Slog.w(TAG, "Unable to launch app "
9392                                        + cpi.applicationInfo.packageName + "/"
9393                                        + cpi.applicationInfo.uid + " for provider "
9394                                        + name + ": process is bad");
9395                                return null;
9396                            }
9397                        }
9398                        cpr.launchingApp = proc;
9399                        mLaunchingProviders.add(cpr);
9400                    } finally {
9401                        Binder.restoreCallingIdentity(origId);
9402                    }
9403                }
9404
9405                checkTime(startTime, "getContentProviderImpl: updating data structures");
9406
9407                // Make sure the provider is published (the same provider class
9408                // may be published under multiple names).
9409                if (firstClass) {
9410                    mProviderMap.putProviderByClass(comp, cpr);
9411                }
9412
9413                mProviderMap.putProviderByName(name, cpr);
9414                conn = incProviderCountLocked(r, cpr, token, stable);
9415                if (conn != null) {
9416                    conn.waiting = true;
9417                }
9418            }
9419            checkTime(startTime, "getContentProviderImpl: done!");
9420        }
9421
9422        // Wait for the provider to be published...
9423        synchronized (cpr) {
9424            while (cpr.provider == null) {
9425                if (cpr.launchingApp == null) {
9426                    Slog.w(TAG, "Unable to launch app "
9427                            + cpi.applicationInfo.packageName + "/"
9428                            + cpi.applicationInfo.uid + " for provider "
9429                            + name + ": launching app became null");
9430                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9431                            UserHandle.getUserId(cpi.applicationInfo.uid),
9432                            cpi.applicationInfo.packageName,
9433                            cpi.applicationInfo.uid, name);
9434                    return null;
9435                }
9436                try {
9437                    if (DEBUG_MU) {
9438                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9439                                + cpr.launchingApp);
9440                    }
9441                    if (conn != null) {
9442                        conn.waiting = true;
9443                    }
9444                    cpr.wait();
9445                } catch (InterruptedException ex) {
9446                } finally {
9447                    if (conn != null) {
9448                        conn.waiting = false;
9449                    }
9450                }
9451            }
9452        }
9453        return cpr != null ? cpr.newHolder(conn) : null;
9454    }
9455
9456    @Override
9457    public final ContentProviderHolder getContentProvider(
9458            IApplicationThread caller, String name, int userId, boolean stable) {
9459        enforceNotIsolatedCaller("getContentProvider");
9460        if (caller == null) {
9461            String msg = "null IApplicationThread when getting content provider "
9462                    + name;
9463            Slog.w(TAG, msg);
9464            throw new SecurityException(msg);
9465        }
9466        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9467        // with cross-user grant.
9468        return getContentProviderImpl(caller, name, null, stable, userId);
9469    }
9470
9471    public ContentProviderHolder getContentProviderExternal(
9472            String name, int userId, IBinder token) {
9473        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9474            "Do not have permission in call getContentProviderExternal()");
9475        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9476                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9477        return getContentProviderExternalUnchecked(name, token, userId);
9478    }
9479
9480    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9481            IBinder token, int userId) {
9482        return getContentProviderImpl(null, name, token, true, userId);
9483    }
9484
9485    /**
9486     * Drop a content provider from a ProcessRecord's bookkeeping
9487     */
9488    public void removeContentProvider(IBinder connection, boolean stable) {
9489        enforceNotIsolatedCaller("removeContentProvider");
9490        long ident = Binder.clearCallingIdentity();
9491        try {
9492            synchronized (this) {
9493                ContentProviderConnection conn;
9494                try {
9495                    conn = (ContentProviderConnection)connection;
9496                } catch (ClassCastException e) {
9497                    String msg ="removeContentProvider: " + connection
9498                            + " not a ContentProviderConnection";
9499                    Slog.w(TAG, msg);
9500                    throw new IllegalArgumentException(msg);
9501                }
9502                if (conn == null) {
9503                    throw new NullPointerException("connection is null");
9504                }
9505                if (decProviderCountLocked(conn, null, null, stable)) {
9506                    updateOomAdjLocked();
9507                }
9508            }
9509        } finally {
9510            Binder.restoreCallingIdentity(ident);
9511        }
9512    }
9513
9514    public void removeContentProviderExternal(String name, IBinder token) {
9515        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9516            "Do not have permission in call removeContentProviderExternal()");
9517        int userId = UserHandle.getCallingUserId();
9518        long ident = Binder.clearCallingIdentity();
9519        try {
9520            removeContentProviderExternalUnchecked(name, token, userId);
9521        } finally {
9522            Binder.restoreCallingIdentity(ident);
9523        }
9524    }
9525
9526    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9527        synchronized (this) {
9528            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9529            if(cpr == null) {
9530                //remove from mProvidersByClass
9531                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9532                return;
9533            }
9534
9535            //update content provider record entry info
9536            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9537            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9538            if (localCpr.hasExternalProcessHandles()) {
9539                if (localCpr.removeExternalProcessHandleLocked(token)) {
9540                    updateOomAdjLocked();
9541                } else {
9542                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9543                            + " with no external reference for token: "
9544                            + token + ".");
9545                }
9546            } else {
9547                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9548                        + " with no external references.");
9549            }
9550        }
9551    }
9552
9553    public final void publishContentProviders(IApplicationThread caller,
9554            List<ContentProviderHolder> providers) {
9555        if (providers == null) {
9556            return;
9557        }
9558
9559        enforceNotIsolatedCaller("publishContentProviders");
9560        synchronized (this) {
9561            final ProcessRecord r = getRecordForAppLocked(caller);
9562            if (DEBUG_MU)
9563                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9564            if (r == null) {
9565                throw new SecurityException(
9566                        "Unable to find app for caller " + caller
9567                      + " (pid=" + Binder.getCallingPid()
9568                      + ") when publishing content providers");
9569            }
9570
9571            final long origId = Binder.clearCallingIdentity();
9572
9573            final int N = providers.size();
9574            for (int i=0; i<N; i++) {
9575                ContentProviderHolder src = providers.get(i);
9576                if (src == null || src.info == null || src.provider == null) {
9577                    continue;
9578                }
9579                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9580                if (DEBUG_MU)
9581                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9582                if (dst != null) {
9583                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9584                    mProviderMap.putProviderByClass(comp, dst);
9585                    String names[] = dst.info.authority.split(";");
9586                    for (int j = 0; j < names.length; j++) {
9587                        mProviderMap.putProviderByName(names[j], dst);
9588                    }
9589
9590                    int NL = mLaunchingProviders.size();
9591                    int j;
9592                    for (j=0; j<NL; j++) {
9593                        if (mLaunchingProviders.get(j) == dst) {
9594                            mLaunchingProviders.remove(j);
9595                            j--;
9596                            NL--;
9597                        }
9598                    }
9599                    synchronized (dst) {
9600                        dst.provider = src.provider;
9601                        dst.proc = r;
9602                        dst.notifyAll();
9603                    }
9604                    updateOomAdjLocked(r);
9605                }
9606            }
9607
9608            Binder.restoreCallingIdentity(origId);
9609        }
9610    }
9611
9612    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9613        ContentProviderConnection conn;
9614        try {
9615            conn = (ContentProviderConnection)connection;
9616        } catch (ClassCastException e) {
9617            String msg ="refContentProvider: " + connection
9618                    + " not a ContentProviderConnection";
9619            Slog.w(TAG, msg);
9620            throw new IllegalArgumentException(msg);
9621        }
9622        if (conn == null) {
9623            throw new NullPointerException("connection is null");
9624        }
9625
9626        synchronized (this) {
9627            if (stable > 0) {
9628                conn.numStableIncs += stable;
9629            }
9630            stable = conn.stableCount + stable;
9631            if (stable < 0) {
9632                throw new IllegalStateException("stableCount < 0: " + stable);
9633            }
9634
9635            if (unstable > 0) {
9636                conn.numUnstableIncs += unstable;
9637            }
9638            unstable = conn.unstableCount + unstable;
9639            if (unstable < 0) {
9640                throw new IllegalStateException("unstableCount < 0: " + unstable);
9641            }
9642
9643            if ((stable+unstable) <= 0) {
9644                throw new IllegalStateException("ref counts can't go to zero here: stable="
9645                        + stable + " unstable=" + unstable);
9646            }
9647            conn.stableCount = stable;
9648            conn.unstableCount = unstable;
9649            return !conn.dead;
9650        }
9651    }
9652
9653    public void unstableProviderDied(IBinder connection) {
9654        ContentProviderConnection conn;
9655        try {
9656            conn = (ContentProviderConnection)connection;
9657        } catch (ClassCastException e) {
9658            String msg ="refContentProvider: " + connection
9659                    + " not a ContentProviderConnection";
9660            Slog.w(TAG, msg);
9661            throw new IllegalArgumentException(msg);
9662        }
9663        if (conn == null) {
9664            throw new NullPointerException("connection is null");
9665        }
9666
9667        // Safely retrieve the content provider associated with the connection.
9668        IContentProvider provider;
9669        synchronized (this) {
9670            provider = conn.provider.provider;
9671        }
9672
9673        if (provider == null) {
9674            // Um, yeah, we're way ahead of you.
9675            return;
9676        }
9677
9678        // Make sure the caller is being honest with us.
9679        if (provider.asBinder().pingBinder()) {
9680            // Er, no, still looks good to us.
9681            synchronized (this) {
9682                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9683                        + " says " + conn + " died, but we don't agree");
9684                return;
9685            }
9686        }
9687
9688        // Well look at that!  It's dead!
9689        synchronized (this) {
9690            if (conn.provider.provider != provider) {
9691                // But something changed...  good enough.
9692                return;
9693            }
9694
9695            ProcessRecord proc = conn.provider.proc;
9696            if (proc == null || proc.thread == null) {
9697                // Seems like the process is already cleaned up.
9698                return;
9699            }
9700
9701            // As far as we're concerned, this is just like receiving a
9702            // death notification...  just a bit prematurely.
9703            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9704                    + ") early provider death");
9705            final long ident = Binder.clearCallingIdentity();
9706            try {
9707                appDiedLocked(proc);
9708            } finally {
9709                Binder.restoreCallingIdentity(ident);
9710            }
9711        }
9712    }
9713
9714    @Override
9715    public void appNotRespondingViaProvider(IBinder connection) {
9716        enforceCallingPermission(
9717                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9718
9719        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9720        if (conn == null) {
9721            Slog.w(TAG, "ContentProviderConnection is null");
9722            return;
9723        }
9724
9725        final ProcessRecord host = conn.provider.proc;
9726        if (host == null) {
9727            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9728            return;
9729        }
9730
9731        final long token = Binder.clearCallingIdentity();
9732        try {
9733            appNotResponding(host, null, null, false, "ContentProvider not responding");
9734        } finally {
9735            Binder.restoreCallingIdentity(token);
9736        }
9737    }
9738
9739    public final void installSystemProviders() {
9740        List<ProviderInfo> providers;
9741        synchronized (this) {
9742            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9743            providers = generateApplicationProvidersLocked(app);
9744            if (providers != null) {
9745                for (int i=providers.size()-1; i>=0; i--) {
9746                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9747                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9748                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9749                                + ": not system .apk");
9750                        providers.remove(i);
9751                    }
9752                }
9753            }
9754        }
9755        if (providers != null) {
9756            mSystemThread.installSystemProviders(providers);
9757        }
9758
9759        mCoreSettingsObserver = new CoreSettingsObserver(this);
9760
9761        //mUsageStatsService.monitorPackages();
9762    }
9763
9764    /**
9765     * Allows apps to retrieve the MIME type of a URI.
9766     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9767     * users, then it does not need permission to access the ContentProvider.
9768     * Either, it needs cross-user uri grants.
9769     *
9770     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9771     *
9772     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9773     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9774     */
9775    public String getProviderMimeType(Uri uri, int userId) {
9776        enforceNotIsolatedCaller("getProviderMimeType");
9777        final String name = uri.getAuthority();
9778        int callingUid = Binder.getCallingUid();
9779        int callingPid = Binder.getCallingPid();
9780        long ident = 0;
9781        boolean clearedIdentity = false;
9782        userId = unsafeConvertIncomingUser(userId);
9783        if (canClearIdentity(callingPid, callingUid, userId)) {
9784            clearedIdentity = true;
9785            ident = Binder.clearCallingIdentity();
9786        }
9787        ContentProviderHolder holder = null;
9788        try {
9789            holder = getContentProviderExternalUnchecked(name, null, userId);
9790            if (holder != null) {
9791                return holder.provider.getType(uri);
9792            }
9793        } catch (RemoteException e) {
9794            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9795            return null;
9796        } finally {
9797            // We need to clear the identity to call removeContentProviderExternalUnchecked
9798            if (!clearedIdentity) {
9799                ident = Binder.clearCallingIdentity();
9800            }
9801            try {
9802                if (holder != null) {
9803                    removeContentProviderExternalUnchecked(name, null, userId);
9804                }
9805            } finally {
9806                Binder.restoreCallingIdentity(ident);
9807            }
9808        }
9809
9810        return null;
9811    }
9812
9813    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9814        if (UserHandle.getUserId(callingUid) == userId) {
9815            return true;
9816        }
9817        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9818                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9819                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9820                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9821                return true;
9822        }
9823        return false;
9824    }
9825
9826    // =========================================================
9827    // GLOBAL MANAGEMENT
9828    // =========================================================
9829
9830    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9831            boolean isolated, int isolatedUid) {
9832        String proc = customProcess != null ? customProcess : info.processName;
9833        BatteryStatsImpl.Uid.Proc ps = null;
9834        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9835        int uid = info.uid;
9836        if (isolated) {
9837            if (isolatedUid == 0) {
9838                int userId = UserHandle.getUserId(uid);
9839                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9840                while (true) {
9841                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9842                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9843                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9844                    }
9845                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9846                    mNextIsolatedProcessUid++;
9847                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9848                        // No process for this uid, use it.
9849                        break;
9850                    }
9851                    stepsLeft--;
9852                    if (stepsLeft <= 0) {
9853                        return null;
9854                    }
9855                }
9856            } else {
9857                // Special case for startIsolatedProcess (internal only), where
9858                // the uid of the isolated process is specified by the caller.
9859                uid = isolatedUid;
9860            }
9861        }
9862        return new ProcessRecord(stats, info, proc, uid);
9863    }
9864
9865    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9866            String abiOverride) {
9867        ProcessRecord app;
9868        if (!isolated) {
9869            app = getProcessRecordLocked(info.processName, info.uid, true);
9870        } else {
9871            app = null;
9872        }
9873
9874        if (app == null) {
9875            app = newProcessRecordLocked(info, null, isolated, 0);
9876            mProcessNames.put(info.processName, app.uid, app);
9877            if (isolated) {
9878                mIsolatedProcesses.put(app.uid, app);
9879            }
9880            updateLruProcessLocked(app, false, null);
9881            updateOomAdjLocked();
9882        }
9883
9884        // This package really, really can not be stopped.
9885        try {
9886            AppGlobals.getPackageManager().setPackageStoppedState(
9887                    info.packageName, false, UserHandle.getUserId(app.uid));
9888        } catch (RemoteException e) {
9889        } catch (IllegalArgumentException e) {
9890            Slog.w(TAG, "Failed trying to unstop package "
9891                    + info.packageName + ": " + e);
9892        }
9893
9894        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9895                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9896            app.persistent = true;
9897            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9898        }
9899        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9900            mPersistentStartingProcesses.add(app);
9901            startProcessLocked(app, "added application", app.processName, abiOverride,
9902                    null /* entryPoint */, null /* entryPointArgs */);
9903        }
9904
9905        return app;
9906    }
9907
9908    public void unhandledBack() {
9909        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9910                "unhandledBack()");
9911
9912        synchronized(this) {
9913            final long origId = Binder.clearCallingIdentity();
9914            try {
9915                getFocusedStack().unhandledBackLocked();
9916            } finally {
9917                Binder.restoreCallingIdentity(origId);
9918            }
9919        }
9920    }
9921
9922    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9923        enforceNotIsolatedCaller("openContentUri");
9924        final int userId = UserHandle.getCallingUserId();
9925        String name = uri.getAuthority();
9926        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9927        ParcelFileDescriptor pfd = null;
9928        if (cph != null) {
9929            // We record the binder invoker's uid in thread-local storage before
9930            // going to the content provider to open the file.  Later, in the code
9931            // that handles all permissions checks, we look for this uid and use
9932            // that rather than the Activity Manager's own uid.  The effect is that
9933            // we do the check against the caller's permissions even though it looks
9934            // to the content provider like the Activity Manager itself is making
9935            // the request.
9936            Binder token = new Binder();
9937            sCallerIdentity.set(new Identity(
9938                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9939            try {
9940                pfd = cph.provider.openFile(null, uri, "r", null, token);
9941            } catch (FileNotFoundException e) {
9942                // do nothing; pfd will be returned null
9943            } finally {
9944                // Ensure that whatever happens, we clean up the identity state
9945                sCallerIdentity.remove();
9946                // Ensure we're done with the provider.
9947                removeContentProviderExternalUnchecked(name, null, userId);
9948            }
9949        } else {
9950            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9951        }
9952        return pfd;
9953    }
9954
9955    // Actually is sleeping or shutting down or whatever else in the future
9956    // is an inactive state.
9957    public boolean isSleepingOrShuttingDown() {
9958        return isSleeping() || mShuttingDown;
9959    }
9960
9961    public boolean isSleeping() {
9962        return mSleeping;
9963    }
9964
9965    void onWakefulnessChanged(int wakefulness) {
9966        synchronized(this) {
9967            mWakefulness = wakefulness;
9968            updateSleepIfNeededLocked();
9969        }
9970    }
9971
9972    void finishRunningVoiceLocked() {
9973        if (mRunningVoice) {
9974            mRunningVoice = false;
9975            updateSleepIfNeededLocked();
9976        }
9977    }
9978
9979    void updateSleepIfNeededLocked() {
9980        if (mSleeping && !shouldSleepLocked()) {
9981            mSleeping = false;
9982            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9983        } else if (!mSleeping && shouldSleepLocked()) {
9984            mSleeping = true;
9985            mStackSupervisor.goingToSleepLocked();
9986
9987            // Initialize the wake times of all processes.
9988            checkExcessivePowerUsageLocked(false);
9989            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9990            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9991            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9992        }
9993    }
9994
9995    private boolean shouldSleepLocked() {
9996        // Resume applications while running a voice interactor.
9997        if (mRunningVoice) {
9998            return false;
9999        }
10000
10001        switch (mWakefulness) {
10002            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10003            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10004                // If we're interactive but applications are already paused then defer
10005                // resuming them until the lock screen is hidden.
10006                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10007            case PowerManagerInternal.WAKEFULNESS_DOZING:
10008                // If we're dozing then pause applications whenever the lock screen is shown.
10009                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10010            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10011            default:
10012                // If we're asleep then pause applications unconditionally.
10013                return true;
10014        }
10015    }
10016
10017    /** Pokes the task persister. */
10018    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10019        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10020            // Never persist the home stack.
10021            return;
10022        }
10023        mTaskPersister.wakeup(task, flush);
10024    }
10025
10026    /** Notifies all listeners when the task stack has changed. */
10027    void notifyTaskStackChangedLocked() {
10028        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10029        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10030        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10031    }
10032
10033    @Override
10034    public boolean shutdown(int timeout) {
10035        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10036                != PackageManager.PERMISSION_GRANTED) {
10037            throw new SecurityException("Requires permission "
10038                    + android.Manifest.permission.SHUTDOWN);
10039        }
10040
10041        boolean timedout = false;
10042
10043        synchronized(this) {
10044            mShuttingDown = true;
10045            updateEventDispatchingLocked();
10046            timedout = mStackSupervisor.shutdownLocked(timeout);
10047        }
10048
10049        mAppOpsService.shutdown();
10050        if (mUsageStatsService != null) {
10051            mUsageStatsService.prepareShutdown();
10052        }
10053        mBatteryStatsService.shutdown();
10054        synchronized (this) {
10055            mProcessStats.shutdownLocked();
10056            notifyTaskPersisterLocked(null, true);
10057        }
10058
10059        return timedout;
10060    }
10061
10062    public final void activitySlept(IBinder token) {
10063        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10064
10065        final long origId = Binder.clearCallingIdentity();
10066
10067        synchronized (this) {
10068            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10069            if (r != null) {
10070                mStackSupervisor.activitySleptLocked(r);
10071            }
10072        }
10073
10074        Binder.restoreCallingIdentity(origId);
10075    }
10076
10077    private String lockScreenShownToString() {
10078        switch (mLockScreenShown) {
10079            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10080            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10081            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10082            default: return "Unknown=" + mLockScreenShown;
10083        }
10084    }
10085
10086    void logLockScreen(String msg) {
10087        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10088                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10089                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10090                + " mSleeping=" + mSleeping);
10091    }
10092
10093    void startRunningVoiceLocked() {
10094        if (!mRunningVoice) {
10095            mRunningVoice = true;
10096            updateSleepIfNeededLocked();
10097        }
10098    }
10099
10100    private void updateEventDispatchingLocked() {
10101        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10102    }
10103
10104    public void setLockScreenShown(boolean shown) {
10105        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10106                != PackageManager.PERMISSION_GRANTED) {
10107            throw new SecurityException("Requires permission "
10108                    + android.Manifest.permission.DEVICE_POWER);
10109        }
10110
10111        synchronized(this) {
10112            long ident = Binder.clearCallingIdentity();
10113            try {
10114                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10115                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10116                updateSleepIfNeededLocked();
10117            } finally {
10118                Binder.restoreCallingIdentity(ident);
10119            }
10120        }
10121    }
10122
10123    @Override
10124    public void stopAppSwitches() {
10125        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10126                != PackageManager.PERMISSION_GRANTED) {
10127            throw new SecurityException("Requires permission "
10128                    + android.Manifest.permission.STOP_APP_SWITCHES);
10129        }
10130
10131        synchronized(this) {
10132            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10133                    + APP_SWITCH_DELAY_TIME;
10134            mDidAppSwitch = false;
10135            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10136            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10137            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10138        }
10139    }
10140
10141    public void resumeAppSwitches() {
10142        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10143                != PackageManager.PERMISSION_GRANTED) {
10144            throw new SecurityException("Requires permission "
10145                    + android.Manifest.permission.STOP_APP_SWITCHES);
10146        }
10147
10148        synchronized(this) {
10149            // Note that we don't execute any pending app switches... we will
10150            // let those wait until either the timeout, or the next start
10151            // activity request.
10152            mAppSwitchesAllowedTime = 0;
10153        }
10154    }
10155
10156    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10157            int callingPid, int callingUid, String name) {
10158        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10159            return true;
10160        }
10161
10162        int perm = checkComponentPermission(
10163                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10164                sourceUid, -1, true);
10165        if (perm == PackageManager.PERMISSION_GRANTED) {
10166            return true;
10167        }
10168
10169        // If the actual IPC caller is different from the logical source, then
10170        // also see if they are allowed to control app switches.
10171        if (callingUid != -1 && callingUid != sourceUid) {
10172            perm = checkComponentPermission(
10173                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10174                    callingUid, -1, true);
10175            if (perm == PackageManager.PERMISSION_GRANTED) {
10176                return true;
10177            }
10178        }
10179
10180        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10181        return false;
10182    }
10183
10184    public void setDebugApp(String packageName, boolean waitForDebugger,
10185            boolean persistent) {
10186        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10187                "setDebugApp()");
10188
10189        long ident = Binder.clearCallingIdentity();
10190        try {
10191            // Note that this is not really thread safe if there are multiple
10192            // callers into it at the same time, but that's not a situation we
10193            // care about.
10194            if (persistent) {
10195                final ContentResolver resolver = mContext.getContentResolver();
10196                Settings.Global.putString(
10197                    resolver, Settings.Global.DEBUG_APP,
10198                    packageName);
10199                Settings.Global.putInt(
10200                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10201                    waitForDebugger ? 1 : 0);
10202            }
10203
10204            synchronized (this) {
10205                if (!persistent) {
10206                    mOrigDebugApp = mDebugApp;
10207                    mOrigWaitForDebugger = mWaitForDebugger;
10208                }
10209                mDebugApp = packageName;
10210                mWaitForDebugger = waitForDebugger;
10211                mDebugTransient = !persistent;
10212                if (packageName != null) {
10213                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10214                            false, UserHandle.USER_ALL, "set debug app");
10215                }
10216            }
10217        } finally {
10218            Binder.restoreCallingIdentity(ident);
10219        }
10220    }
10221
10222    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10223        synchronized (this) {
10224            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10225            if (!isDebuggable) {
10226                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10227                    throw new SecurityException("Process not debuggable: " + app.packageName);
10228                }
10229            }
10230
10231            mOpenGlTraceApp = processName;
10232        }
10233    }
10234
10235    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10236        synchronized (this) {
10237            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10238            if (!isDebuggable) {
10239                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10240                    throw new SecurityException("Process not debuggable: " + app.packageName);
10241                }
10242            }
10243            mProfileApp = processName;
10244            mProfileFile = profilerInfo.profileFile;
10245            if (mProfileFd != null) {
10246                try {
10247                    mProfileFd.close();
10248                } catch (IOException e) {
10249                }
10250                mProfileFd = null;
10251            }
10252            mProfileFd = profilerInfo.profileFd;
10253            mSamplingInterval = profilerInfo.samplingInterval;
10254            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10255            mProfileType = 0;
10256        }
10257    }
10258
10259    @Override
10260    public void setAlwaysFinish(boolean enabled) {
10261        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10262                "setAlwaysFinish()");
10263
10264        Settings.Global.putInt(
10265                mContext.getContentResolver(),
10266                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10267
10268        synchronized (this) {
10269            mAlwaysFinishActivities = enabled;
10270        }
10271    }
10272
10273    @Override
10274    public void setActivityController(IActivityController controller) {
10275        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10276                "setActivityController()");
10277        synchronized (this) {
10278            mController = controller;
10279            Watchdog.getInstance().setActivityController(controller);
10280        }
10281    }
10282
10283    @Override
10284    public void setUserIsMonkey(boolean userIsMonkey) {
10285        synchronized (this) {
10286            synchronized (mPidsSelfLocked) {
10287                final int callingPid = Binder.getCallingPid();
10288                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10289                if (precessRecord == null) {
10290                    throw new SecurityException("Unknown process: " + callingPid);
10291                }
10292                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10293                    throw new SecurityException("Only an instrumentation process "
10294                            + "with a UiAutomation can call setUserIsMonkey");
10295                }
10296            }
10297            mUserIsMonkey = userIsMonkey;
10298        }
10299    }
10300
10301    @Override
10302    public boolean isUserAMonkey() {
10303        synchronized (this) {
10304            // If there is a controller also implies the user is a monkey.
10305            return (mUserIsMonkey || mController != null);
10306        }
10307    }
10308
10309    public void requestBugReport() {
10310        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10311        SystemProperties.set("ctl.start", "bugreport");
10312    }
10313
10314    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10315        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10316    }
10317
10318    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10319        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10320            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10321        }
10322        return KEY_DISPATCHING_TIMEOUT;
10323    }
10324
10325    @Override
10326    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10327        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10328                != PackageManager.PERMISSION_GRANTED) {
10329            throw new SecurityException("Requires permission "
10330                    + android.Manifest.permission.FILTER_EVENTS);
10331        }
10332        ProcessRecord proc;
10333        long timeout;
10334        synchronized (this) {
10335            synchronized (mPidsSelfLocked) {
10336                proc = mPidsSelfLocked.get(pid);
10337            }
10338            timeout = getInputDispatchingTimeoutLocked(proc);
10339        }
10340
10341        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10342            return -1;
10343        }
10344
10345        return timeout;
10346    }
10347
10348    /**
10349     * Handle input dispatching timeouts.
10350     * Returns whether input dispatching should be aborted or not.
10351     */
10352    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10353            final ActivityRecord activity, final ActivityRecord parent,
10354            final boolean aboveSystem, String reason) {
10355        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10356                != PackageManager.PERMISSION_GRANTED) {
10357            throw new SecurityException("Requires permission "
10358                    + android.Manifest.permission.FILTER_EVENTS);
10359        }
10360
10361        final String annotation;
10362        if (reason == null) {
10363            annotation = "Input dispatching timed out";
10364        } else {
10365            annotation = "Input dispatching timed out (" + reason + ")";
10366        }
10367
10368        if (proc != null) {
10369            synchronized (this) {
10370                if (proc.debugging) {
10371                    return false;
10372                }
10373
10374                if (mDidDexOpt) {
10375                    // Give more time since we were dexopting.
10376                    mDidDexOpt = false;
10377                    return false;
10378                }
10379
10380                if (proc.instrumentationClass != null) {
10381                    Bundle info = new Bundle();
10382                    info.putString("shortMsg", "keyDispatchingTimedOut");
10383                    info.putString("longMsg", annotation);
10384                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10385                    return true;
10386                }
10387            }
10388            mHandler.post(new Runnable() {
10389                @Override
10390                public void run() {
10391                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10392                }
10393            });
10394        }
10395
10396        return true;
10397    }
10398
10399    public Bundle getAssistContextExtras(int requestType) {
10400        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10401                UserHandle.getCallingUserId());
10402        if (pae == null) {
10403            return null;
10404        }
10405        synchronized (pae) {
10406            while (!pae.haveResult) {
10407                try {
10408                    pae.wait();
10409                } catch (InterruptedException e) {
10410                }
10411            }
10412            if (pae.result != null) {
10413                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10414            }
10415        }
10416        synchronized (this) {
10417            mPendingAssistExtras.remove(pae);
10418            mHandler.removeCallbacks(pae);
10419        }
10420        return pae.extras;
10421    }
10422
10423    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10424            int userHandle) {
10425        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10426                "getAssistContextExtras()");
10427        PendingAssistExtras pae;
10428        Bundle extras = new Bundle();
10429        synchronized (this) {
10430            ActivityRecord activity = getFocusedStack().mResumedActivity;
10431            if (activity == null) {
10432                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10433                return null;
10434            }
10435            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10436            if (activity.app == null || activity.app.thread == null) {
10437                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10438                return null;
10439            }
10440            if (activity.app.pid == Binder.getCallingPid()) {
10441                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10442                return null;
10443            }
10444            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10445            try {
10446                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10447                        requestType);
10448                mPendingAssistExtras.add(pae);
10449                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10450            } catch (RemoteException e) {
10451                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10452                return null;
10453            }
10454            return pae;
10455        }
10456    }
10457
10458    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10459        PendingAssistExtras pae = (PendingAssistExtras)token;
10460        synchronized (pae) {
10461            pae.result = extras;
10462            pae.haveResult = true;
10463            pae.notifyAll();
10464            if (pae.intent == null) {
10465                // Caller is just waiting for the result.
10466                return;
10467            }
10468        }
10469
10470        // We are now ready to launch the assist activity.
10471        synchronized (this) {
10472            boolean exists = mPendingAssistExtras.remove(pae);
10473            mHandler.removeCallbacks(pae);
10474            if (!exists) {
10475                // Timed out.
10476                return;
10477            }
10478        }
10479        pae.intent.replaceExtras(extras);
10480        if (pae.hint != null) {
10481            pae.intent.putExtra(pae.hint, true);
10482        }
10483        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10484                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10485                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10486        closeSystemDialogs("assist");
10487        try {
10488            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10489        } catch (ActivityNotFoundException e) {
10490            Slog.w(TAG, "No activity to handle assist action.", e);
10491        }
10492    }
10493
10494    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10495        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10496    }
10497
10498    public void registerProcessObserver(IProcessObserver observer) {
10499        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10500                "registerProcessObserver()");
10501        synchronized (this) {
10502            mProcessObservers.register(observer);
10503        }
10504    }
10505
10506    @Override
10507    public void unregisterProcessObserver(IProcessObserver observer) {
10508        synchronized (this) {
10509            mProcessObservers.unregister(observer);
10510        }
10511    }
10512
10513    @Override
10514    public boolean convertFromTranslucent(IBinder token) {
10515        final long origId = Binder.clearCallingIdentity();
10516        try {
10517            synchronized (this) {
10518                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10519                if (r == null) {
10520                    return false;
10521                }
10522                final boolean translucentChanged = r.changeWindowTranslucency(true);
10523                if (translucentChanged) {
10524                    r.task.stack.releaseBackgroundResources();
10525                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10526                }
10527                mWindowManager.setAppFullscreen(token, true);
10528                return translucentChanged;
10529            }
10530        } finally {
10531            Binder.restoreCallingIdentity(origId);
10532        }
10533    }
10534
10535    @Override
10536    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10537        final long origId = Binder.clearCallingIdentity();
10538        try {
10539            synchronized (this) {
10540                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10541                if (r == null) {
10542                    return false;
10543                }
10544                int index = r.task.mActivities.lastIndexOf(r);
10545                if (index > 0) {
10546                    ActivityRecord under = r.task.mActivities.get(index - 1);
10547                    under.returningOptions = options;
10548                }
10549                final boolean translucentChanged = r.changeWindowTranslucency(false);
10550                if (translucentChanged) {
10551                    r.task.stack.convertToTranslucent(r);
10552                }
10553                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10554                mWindowManager.setAppFullscreen(token, false);
10555                return translucentChanged;
10556            }
10557        } finally {
10558            Binder.restoreCallingIdentity(origId);
10559        }
10560    }
10561
10562    @Override
10563    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10564        final long origId = Binder.clearCallingIdentity();
10565        try {
10566            synchronized (this) {
10567                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10568                if (r != null) {
10569                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10570                }
10571            }
10572            return false;
10573        } finally {
10574            Binder.restoreCallingIdentity(origId);
10575        }
10576    }
10577
10578    @Override
10579    public boolean isBackgroundVisibleBehind(IBinder token) {
10580        final long origId = Binder.clearCallingIdentity();
10581        try {
10582            synchronized (this) {
10583                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10584                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10585                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10586                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10587                return visible;
10588            }
10589        } finally {
10590            Binder.restoreCallingIdentity(origId);
10591        }
10592    }
10593
10594    @Override
10595    public ActivityOptions getActivityOptions(IBinder token) {
10596        final long origId = Binder.clearCallingIdentity();
10597        try {
10598            synchronized (this) {
10599                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10600                if (r != null) {
10601                    final ActivityOptions activityOptions = r.pendingOptions;
10602                    r.pendingOptions = null;
10603                    return activityOptions;
10604                }
10605                return null;
10606            }
10607        } finally {
10608            Binder.restoreCallingIdentity(origId);
10609        }
10610    }
10611
10612    @Override
10613    public void setImmersive(IBinder token, boolean immersive) {
10614        synchronized(this) {
10615            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10616            if (r == null) {
10617                throw new IllegalArgumentException();
10618            }
10619            r.immersive = immersive;
10620
10621            // update associated state if we're frontmost
10622            if (r == mFocusedActivity) {
10623                if (DEBUG_IMMERSIVE) {
10624                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10625                }
10626                applyUpdateLockStateLocked(r);
10627            }
10628        }
10629    }
10630
10631    @Override
10632    public boolean isImmersive(IBinder token) {
10633        synchronized (this) {
10634            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10635            if (r == null) {
10636                throw new IllegalArgumentException();
10637            }
10638            return r.immersive;
10639        }
10640    }
10641
10642    public boolean isTopActivityImmersive() {
10643        enforceNotIsolatedCaller("startActivity");
10644        synchronized (this) {
10645            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10646            return (r != null) ? r.immersive : false;
10647        }
10648    }
10649
10650    @Override
10651    public boolean isTopOfTask(IBinder token) {
10652        synchronized (this) {
10653            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10654            if (r == null) {
10655                throw new IllegalArgumentException();
10656            }
10657            return r.task.getTopActivity() == r;
10658        }
10659    }
10660
10661    public final void enterSafeMode() {
10662        synchronized(this) {
10663            // It only makes sense to do this before the system is ready
10664            // and started launching other packages.
10665            if (!mSystemReady) {
10666                try {
10667                    AppGlobals.getPackageManager().enterSafeMode();
10668                } catch (RemoteException e) {
10669                }
10670            }
10671
10672            mSafeMode = true;
10673        }
10674    }
10675
10676    public final void showSafeModeOverlay() {
10677        View v = LayoutInflater.from(mContext).inflate(
10678                com.android.internal.R.layout.safe_mode, null);
10679        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10680        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10681        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10682        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10683        lp.gravity = Gravity.BOTTOM | Gravity.START;
10684        lp.format = v.getBackground().getOpacity();
10685        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10686                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10687        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10688        ((WindowManager)mContext.getSystemService(
10689                Context.WINDOW_SERVICE)).addView(v, lp);
10690    }
10691
10692    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10693        if (!(sender instanceof PendingIntentRecord)) {
10694            return;
10695        }
10696        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10697        synchronized (stats) {
10698            if (mBatteryStatsService.isOnBattery()) {
10699                mBatteryStatsService.enforceCallingPermission();
10700                PendingIntentRecord rec = (PendingIntentRecord)sender;
10701                int MY_UID = Binder.getCallingUid();
10702                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10703                BatteryStatsImpl.Uid.Pkg pkg =
10704                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10705                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10706                pkg.incWakeupsLocked();
10707            }
10708        }
10709    }
10710
10711    public boolean killPids(int[] pids, String pReason, boolean secure) {
10712        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10713            throw new SecurityException("killPids only available to the system");
10714        }
10715        String reason = (pReason == null) ? "Unknown" : pReason;
10716        // XXX Note: don't acquire main activity lock here, because the window
10717        // manager calls in with its locks held.
10718
10719        boolean killed = false;
10720        synchronized (mPidsSelfLocked) {
10721            int[] types = new int[pids.length];
10722            int worstType = 0;
10723            for (int i=0; i<pids.length; i++) {
10724                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10725                if (proc != null) {
10726                    int type = proc.setAdj;
10727                    types[i] = type;
10728                    if (type > worstType) {
10729                        worstType = type;
10730                    }
10731                }
10732            }
10733
10734            // If the worst oom_adj is somewhere in the cached proc LRU range,
10735            // then constrain it so we will kill all cached procs.
10736            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10737                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10738                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10739            }
10740
10741            // If this is not a secure call, don't let it kill processes that
10742            // are important.
10743            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10744                worstType = ProcessList.SERVICE_ADJ;
10745            }
10746
10747            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10748            for (int i=0; i<pids.length; i++) {
10749                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10750                if (proc == null) {
10751                    continue;
10752                }
10753                int adj = proc.setAdj;
10754                if (adj >= worstType && !proc.killedByAm) {
10755                    proc.kill(reason, true);
10756                    killed = true;
10757                }
10758            }
10759        }
10760        return killed;
10761    }
10762
10763    @Override
10764    public void killUid(int uid, String reason) {
10765        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10766            throw new SecurityException("killUid only available to the system");
10767        }
10768        synchronized (this) {
10769            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10770                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10771                    reason != null ? reason : "kill uid");
10772        }
10773    }
10774
10775    @Override
10776    public boolean killProcessesBelowForeground(String reason) {
10777        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10778            throw new SecurityException("killProcessesBelowForeground() only available to system");
10779        }
10780
10781        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10782    }
10783
10784    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10785        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10786            throw new SecurityException("killProcessesBelowAdj() only available to system");
10787        }
10788
10789        boolean killed = false;
10790        synchronized (mPidsSelfLocked) {
10791            final int size = mPidsSelfLocked.size();
10792            for (int i = 0; i < size; i++) {
10793                final int pid = mPidsSelfLocked.keyAt(i);
10794                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10795                if (proc == null) continue;
10796
10797                final int adj = proc.setAdj;
10798                if (adj > belowAdj && !proc.killedByAm) {
10799                    proc.kill(reason, true);
10800                    killed = true;
10801                }
10802            }
10803        }
10804        return killed;
10805    }
10806
10807    @Override
10808    public void hang(final IBinder who, boolean allowRestart) {
10809        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10810                != PackageManager.PERMISSION_GRANTED) {
10811            throw new SecurityException("Requires permission "
10812                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10813        }
10814
10815        final IBinder.DeathRecipient death = new DeathRecipient() {
10816            @Override
10817            public void binderDied() {
10818                synchronized (this) {
10819                    notifyAll();
10820                }
10821            }
10822        };
10823
10824        try {
10825            who.linkToDeath(death, 0);
10826        } catch (RemoteException e) {
10827            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10828            return;
10829        }
10830
10831        synchronized (this) {
10832            Watchdog.getInstance().setAllowRestart(allowRestart);
10833            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10834            synchronized (death) {
10835                while (who.isBinderAlive()) {
10836                    try {
10837                        death.wait();
10838                    } catch (InterruptedException e) {
10839                    }
10840                }
10841            }
10842            Watchdog.getInstance().setAllowRestart(true);
10843        }
10844    }
10845
10846    @Override
10847    public void restart() {
10848        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10849                != PackageManager.PERMISSION_GRANTED) {
10850            throw new SecurityException("Requires permission "
10851                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10852        }
10853
10854        Log.i(TAG, "Sending shutdown broadcast...");
10855
10856        BroadcastReceiver br = new BroadcastReceiver() {
10857            @Override public void onReceive(Context context, Intent intent) {
10858                // Now the broadcast is done, finish up the low-level shutdown.
10859                Log.i(TAG, "Shutting down activity manager...");
10860                shutdown(10000);
10861                Log.i(TAG, "Shutdown complete, restarting!");
10862                Process.killProcess(Process.myPid());
10863                System.exit(10);
10864            }
10865        };
10866
10867        // First send the high-level shut down broadcast.
10868        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10869        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10870        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10871        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10872        mContext.sendOrderedBroadcastAsUser(intent,
10873                UserHandle.ALL, null, br, mHandler, 0, null, null);
10874        */
10875        br.onReceive(mContext, intent);
10876    }
10877
10878    private long getLowRamTimeSinceIdle(long now) {
10879        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10880    }
10881
10882    @Override
10883    public void performIdleMaintenance() {
10884        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10885                != PackageManager.PERMISSION_GRANTED) {
10886            throw new SecurityException("Requires permission "
10887                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10888        }
10889
10890        synchronized (this) {
10891            final long now = SystemClock.uptimeMillis();
10892            final long timeSinceLastIdle = now - mLastIdleTime;
10893            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10894            mLastIdleTime = now;
10895            mLowRamTimeSinceLastIdle = 0;
10896            if (mLowRamStartTime != 0) {
10897                mLowRamStartTime = now;
10898            }
10899
10900            StringBuilder sb = new StringBuilder(128);
10901            sb.append("Idle maintenance over ");
10902            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10903            sb.append(" low RAM for ");
10904            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10905            Slog.i(TAG, sb.toString());
10906
10907            // If at least 1/3 of our time since the last idle period has been spent
10908            // with RAM low, then we want to kill processes.
10909            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10910
10911            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10912                ProcessRecord proc = mLruProcesses.get(i);
10913                if (proc.notCachedSinceIdle) {
10914                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10915                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10916                        if (doKilling && proc.initialIdlePss != 0
10917                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10918                            proc.kill("idle maint (pss " + proc.lastPss
10919                                    + " from " + proc.initialIdlePss + ")", true);
10920                        }
10921                    }
10922                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10923                    proc.notCachedSinceIdle = true;
10924                    proc.initialIdlePss = 0;
10925                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10926                            isSleeping(), now);
10927                }
10928            }
10929
10930            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10931            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10932        }
10933    }
10934
10935    private void retrieveSettings() {
10936        final ContentResolver resolver = mContext.getContentResolver();
10937        String debugApp = Settings.Global.getString(
10938            resolver, Settings.Global.DEBUG_APP);
10939        boolean waitForDebugger = Settings.Global.getInt(
10940            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10941        boolean alwaysFinishActivities = Settings.Global.getInt(
10942            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10943        boolean forceRtl = Settings.Global.getInt(
10944                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10945        // Transfer any global setting for forcing RTL layout, into a System Property
10946        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10947
10948        Configuration configuration = new Configuration();
10949        Settings.System.getConfiguration(resolver, configuration);
10950        if (forceRtl) {
10951            // This will take care of setting the correct layout direction flags
10952            configuration.setLayoutDirection(configuration.locale);
10953        }
10954
10955        synchronized (this) {
10956            mDebugApp = mOrigDebugApp = debugApp;
10957            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10958            mAlwaysFinishActivities = alwaysFinishActivities;
10959            // This happens before any activities are started, so we can
10960            // change mConfiguration in-place.
10961            updateConfigurationLocked(configuration, null, false, true);
10962            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10963        }
10964    }
10965
10966    /** Loads resources after the current configuration has been set. */
10967    private void loadResourcesOnSystemReady() {
10968        final Resources res = mContext.getResources();
10969        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10970        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10971        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10972    }
10973
10974    public boolean testIsSystemReady() {
10975        // no need to synchronize(this) just to read & return the value
10976        return mSystemReady;
10977    }
10978
10979    private static File getCalledPreBootReceiversFile() {
10980        File dataDir = Environment.getDataDirectory();
10981        File systemDir = new File(dataDir, "system");
10982        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10983        return fname;
10984    }
10985
10986    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10987        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10988        File file = getCalledPreBootReceiversFile();
10989        FileInputStream fis = null;
10990        try {
10991            fis = new FileInputStream(file);
10992            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10993            int fvers = dis.readInt();
10994            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10995                String vers = dis.readUTF();
10996                String codename = dis.readUTF();
10997                String build = dis.readUTF();
10998                if (android.os.Build.VERSION.RELEASE.equals(vers)
10999                        && android.os.Build.VERSION.CODENAME.equals(codename)
11000                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11001                    int num = dis.readInt();
11002                    while (num > 0) {
11003                        num--;
11004                        String pkg = dis.readUTF();
11005                        String cls = dis.readUTF();
11006                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11007                    }
11008                }
11009            }
11010        } catch (FileNotFoundException e) {
11011        } catch (IOException e) {
11012            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11013        } finally {
11014            if (fis != null) {
11015                try {
11016                    fis.close();
11017                } catch (IOException e) {
11018                }
11019            }
11020        }
11021        return lastDoneReceivers;
11022    }
11023
11024    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11025        File file = getCalledPreBootReceiversFile();
11026        FileOutputStream fos = null;
11027        DataOutputStream dos = null;
11028        try {
11029            fos = new FileOutputStream(file);
11030            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11031            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11032            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11033            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11034            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11035            dos.writeInt(list.size());
11036            for (int i=0; i<list.size(); i++) {
11037                dos.writeUTF(list.get(i).getPackageName());
11038                dos.writeUTF(list.get(i).getClassName());
11039            }
11040        } catch (IOException e) {
11041            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11042            file.delete();
11043        } finally {
11044            FileUtils.sync(fos);
11045            if (dos != null) {
11046                try {
11047                    dos.close();
11048                } catch (IOException e) {
11049                    // TODO Auto-generated catch block
11050                    e.printStackTrace();
11051                }
11052            }
11053        }
11054    }
11055
11056    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11057            ArrayList<ComponentName> doneReceivers, int userId) {
11058        boolean waitingUpdate = false;
11059        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11060        List<ResolveInfo> ris = null;
11061        try {
11062            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11063                    intent, null, 0, userId);
11064        } catch (RemoteException e) {
11065        }
11066        if (ris != null) {
11067            for (int i=ris.size()-1; i>=0; i--) {
11068                if ((ris.get(i).activityInfo.applicationInfo.flags
11069                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11070                    ris.remove(i);
11071                }
11072            }
11073            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11074
11075            // For User 0, load the version number. When delivering to a new user, deliver
11076            // to all receivers.
11077            if (userId == UserHandle.USER_OWNER) {
11078                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11079                for (int i=0; i<ris.size(); i++) {
11080                    ActivityInfo ai = ris.get(i).activityInfo;
11081                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11082                    if (lastDoneReceivers.contains(comp)) {
11083                        // We already did the pre boot receiver for this app with the current
11084                        // platform version, so don't do it again...
11085                        ris.remove(i);
11086                        i--;
11087                        // ...however, do keep it as one that has been done, so we don't
11088                        // forget about it when rewriting the file of last done receivers.
11089                        doneReceivers.add(comp);
11090                    }
11091                }
11092            }
11093
11094            // If primary user, send broadcast to all available users, else just to userId
11095            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11096                    : new int[] { userId };
11097            for (int i = 0; i < ris.size(); i++) {
11098                ActivityInfo ai = ris.get(i).activityInfo;
11099                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11100                doneReceivers.add(comp);
11101                intent.setComponent(comp);
11102                for (int j=0; j<users.length; j++) {
11103                    IIntentReceiver finisher = null;
11104                    // On last receiver and user, set up a completion callback
11105                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11106                        finisher = new IIntentReceiver.Stub() {
11107                            public void performReceive(Intent intent, int resultCode,
11108                                    String data, Bundle extras, boolean ordered,
11109                                    boolean sticky, int sendingUser) {
11110                                // The raw IIntentReceiver interface is called
11111                                // with the AM lock held, so redispatch to
11112                                // execute our code without the lock.
11113                                mHandler.post(onFinishCallback);
11114                            }
11115                        };
11116                    }
11117                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11118                            + " for user " + users[j]);
11119                    broadcastIntentLocked(null, null, intent, null, finisher,
11120                            0, null, null, null, AppOpsManager.OP_NONE,
11121                            true, false, MY_PID, Process.SYSTEM_UID,
11122                            users[j]);
11123                    if (finisher != null) {
11124                        waitingUpdate = true;
11125                    }
11126                }
11127            }
11128        }
11129
11130        return waitingUpdate;
11131    }
11132
11133    public void systemReady(final Runnable goingCallback) {
11134        synchronized(this) {
11135            if (mSystemReady) {
11136                // If we're done calling all the receivers, run the next "boot phase" passed in
11137                // by the SystemServer
11138                if (goingCallback != null) {
11139                    goingCallback.run();
11140                }
11141                return;
11142            }
11143
11144            // Make sure we have the current profile info, since it is needed for
11145            // security checks.
11146            updateCurrentProfileIdsLocked();
11147
11148            if (mRecentTasks == null) {
11149                mRecentTasks = mTaskPersister.restoreTasksLocked();
11150                if (!mRecentTasks.isEmpty()) {
11151                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11152                }
11153                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11154                mTaskPersister.startPersisting();
11155            }
11156
11157            // Check to see if there are any update receivers to run.
11158            if (!mDidUpdate) {
11159                if (mWaitingUpdate) {
11160                    return;
11161                }
11162                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11163                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11164                    public void run() {
11165                        synchronized (ActivityManagerService.this) {
11166                            mDidUpdate = true;
11167                        }
11168                        writeLastDonePreBootReceivers(doneReceivers);
11169                        showBootMessage(mContext.getText(
11170                                R.string.android_upgrading_complete),
11171                                false);
11172                        systemReady(goingCallback);
11173                    }
11174                }, doneReceivers, UserHandle.USER_OWNER);
11175
11176                if (mWaitingUpdate) {
11177                    return;
11178                }
11179                mDidUpdate = true;
11180            }
11181
11182            mAppOpsService.systemReady();
11183            mSystemReady = true;
11184        }
11185
11186        ArrayList<ProcessRecord> procsToKill = null;
11187        synchronized(mPidsSelfLocked) {
11188            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11189                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11190                if (!isAllowedWhileBooting(proc.info)){
11191                    if (procsToKill == null) {
11192                        procsToKill = new ArrayList<ProcessRecord>();
11193                    }
11194                    procsToKill.add(proc);
11195                }
11196            }
11197        }
11198
11199        synchronized(this) {
11200            if (procsToKill != null) {
11201                for (int i=procsToKill.size()-1; i>=0; i--) {
11202                    ProcessRecord proc = procsToKill.get(i);
11203                    Slog.i(TAG, "Removing system update proc: " + proc);
11204                    removeProcessLocked(proc, true, false, "system update done");
11205                }
11206            }
11207
11208            // Now that we have cleaned up any update processes, we
11209            // are ready to start launching real processes and know that
11210            // we won't trample on them any more.
11211            mProcessesReady = true;
11212        }
11213
11214        Slog.i(TAG, "System now ready");
11215        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11216            SystemClock.uptimeMillis());
11217
11218        synchronized(this) {
11219            // Make sure we have no pre-ready processes sitting around.
11220
11221            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11222                ResolveInfo ri = mContext.getPackageManager()
11223                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11224                                STOCK_PM_FLAGS);
11225                CharSequence errorMsg = null;
11226                if (ri != null) {
11227                    ActivityInfo ai = ri.activityInfo;
11228                    ApplicationInfo app = ai.applicationInfo;
11229                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11230                        mTopAction = Intent.ACTION_FACTORY_TEST;
11231                        mTopData = null;
11232                        mTopComponent = new ComponentName(app.packageName,
11233                                ai.name);
11234                    } else {
11235                        errorMsg = mContext.getResources().getText(
11236                                com.android.internal.R.string.factorytest_not_system);
11237                    }
11238                } else {
11239                    errorMsg = mContext.getResources().getText(
11240                            com.android.internal.R.string.factorytest_no_action);
11241                }
11242                if (errorMsg != null) {
11243                    mTopAction = null;
11244                    mTopData = null;
11245                    mTopComponent = null;
11246                    Message msg = Message.obtain();
11247                    msg.what = SHOW_FACTORY_ERROR_MSG;
11248                    msg.getData().putCharSequence("msg", errorMsg);
11249                    mHandler.sendMessage(msg);
11250                }
11251            }
11252        }
11253
11254        retrieveSettings();
11255        loadResourcesOnSystemReady();
11256
11257        synchronized (this) {
11258            readGrantedUriPermissionsLocked();
11259        }
11260
11261        if (goingCallback != null) goingCallback.run();
11262
11263        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11264                Integer.toString(mCurrentUserId), mCurrentUserId);
11265        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11266                Integer.toString(mCurrentUserId), mCurrentUserId);
11267        mSystemServiceManager.startUser(mCurrentUserId);
11268
11269        synchronized (this) {
11270            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11271                try {
11272                    List apps = AppGlobals.getPackageManager().
11273                        getPersistentApplications(STOCK_PM_FLAGS);
11274                    if (apps != null) {
11275                        int N = apps.size();
11276                        int i;
11277                        for (i=0; i<N; i++) {
11278                            ApplicationInfo info
11279                                = (ApplicationInfo)apps.get(i);
11280                            if (info != null &&
11281                                    !info.packageName.equals("android")) {
11282                                addAppLocked(info, false, null /* ABI override */);
11283                            }
11284                        }
11285                    }
11286                } catch (RemoteException ex) {
11287                    // pm is in same process, this will never happen.
11288                }
11289            }
11290
11291            // Start up initial activity.
11292            mBooting = true;
11293            startHomeActivityLocked(mCurrentUserId);
11294
11295            try {
11296                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11297                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11298                            + " data partition or your device will be unstable.");
11299                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11300                }
11301            } catch (RemoteException e) {
11302            }
11303
11304            if (!Build.isFingerprintConsistent()) {
11305                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11306                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11307            }
11308
11309            long ident = Binder.clearCallingIdentity();
11310            try {
11311                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11312                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11313                        | Intent.FLAG_RECEIVER_FOREGROUND);
11314                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11315                broadcastIntentLocked(null, null, intent,
11316                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11317                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11318                intent = new Intent(Intent.ACTION_USER_STARTING);
11319                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11320                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11321                broadcastIntentLocked(null, null, intent,
11322                        null, new IIntentReceiver.Stub() {
11323                            @Override
11324                            public void performReceive(Intent intent, int resultCode, String data,
11325                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11326                                    throws RemoteException {
11327                            }
11328                        }, 0, null, null,
11329                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11330                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11331            } catch (Throwable t) {
11332                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11333            } finally {
11334                Binder.restoreCallingIdentity(ident);
11335            }
11336            mStackSupervisor.resumeTopActivitiesLocked();
11337            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11338        }
11339    }
11340
11341    private boolean makeAppCrashingLocked(ProcessRecord app,
11342            String shortMsg, String longMsg, String stackTrace) {
11343        app.crashing = true;
11344        app.crashingReport = generateProcessError(app,
11345                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11346        startAppProblemLocked(app);
11347        app.stopFreezingAllLocked();
11348        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11349    }
11350
11351    private void makeAppNotRespondingLocked(ProcessRecord app,
11352            String activity, String shortMsg, String longMsg) {
11353        app.notResponding = true;
11354        app.notRespondingReport = generateProcessError(app,
11355                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11356                activity, shortMsg, longMsg, null);
11357        startAppProblemLocked(app);
11358        app.stopFreezingAllLocked();
11359    }
11360
11361    /**
11362     * Generate a process error record, suitable for attachment to a ProcessRecord.
11363     *
11364     * @param app The ProcessRecord in which the error occurred.
11365     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11366     *                      ActivityManager.AppErrorStateInfo
11367     * @param activity The activity associated with the crash, if known.
11368     * @param shortMsg Short message describing the crash.
11369     * @param longMsg Long message describing the crash.
11370     * @param stackTrace Full crash stack trace, may be null.
11371     *
11372     * @return Returns a fully-formed AppErrorStateInfo record.
11373     */
11374    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11375            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11376        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11377
11378        report.condition = condition;
11379        report.processName = app.processName;
11380        report.pid = app.pid;
11381        report.uid = app.info.uid;
11382        report.tag = activity;
11383        report.shortMsg = shortMsg;
11384        report.longMsg = longMsg;
11385        report.stackTrace = stackTrace;
11386
11387        return report;
11388    }
11389
11390    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11391        synchronized (this) {
11392            app.crashing = false;
11393            app.crashingReport = null;
11394            app.notResponding = false;
11395            app.notRespondingReport = null;
11396            if (app.anrDialog == fromDialog) {
11397                app.anrDialog = null;
11398            }
11399            if (app.waitDialog == fromDialog) {
11400                app.waitDialog = null;
11401            }
11402            if (app.pid > 0 && app.pid != MY_PID) {
11403                handleAppCrashLocked(app, null, null, null);
11404                app.kill("user request after error", true);
11405            }
11406        }
11407    }
11408
11409    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11410            String stackTrace) {
11411        long now = SystemClock.uptimeMillis();
11412
11413        Long crashTime;
11414        if (!app.isolated) {
11415            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11416        } else {
11417            crashTime = null;
11418        }
11419        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11420            // This process loses!
11421            Slog.w(TAG, "Process " + app.info.processName
11422                    + " has crashed too many times: killing!");
11423            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11424                    app.userId, app.info.processName, app.uid);
11425            mStackSupervisor.handleAppCrashLocked(app);
11426            if (!app.persistent) {
11427                // We don't want to start this process again until the user
11428                // explicitly does so...  but for persistent process, we really
11429                // need to keep it running.  If a persistent process is actually
11430                // repeatedly crashing, then badness for everyone.
11431                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11432                        app.info.processName);
11433                if (!app.isolated) {
11434                    // XXX We don't have a way to mark isolated processes
11435                    // as bad, since they don't have a peristent identity.
11436                    mBadProcesses.put(app.info.processName, app.uid,
11437                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11438                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11439                }
11440                app.bad = true;
11441                app.removed = true;
11442                // Don't let services in this process be restarted and potentially
11443                // annoy the user repeatedly.  Unless it is persistent, since those
11444                // processes run critical code.
11445                removeProcessLocked(app, false, false, "crash");
11446                mStackSupervisor.resumeTopActivitiesLocked();
11447                return false;
11448            }
11449            mStackSupervisor.resumeTopActivitiesLocked();
11450        } else {
11451            mStackSupervisor.finishTopRunningActivityLocked(app);
11452        }
11453
11454        // Bump up the crash count of any services currently running in the proc.
11455        for (int i=app.services.size()-1; i>=0; i--) {
11456            // Any services running in the application need to be placed
11457            // back in the pending list.
11458            ServiceRecord sr = app.services.valueAt(i);
11459            sr.crashCount++;
11460        }
11461
11462        // If the crashing process is what we consider to be the "home process" and it has been
11463        // replaced by a third-party app, clear the package preferred activities from packages
11464        // with a home activity running in the process to prevent a repeatedly crashing app
11465        // from blocking the user to manually clear the list.
11466        final ArrayList<ActivityRecord> activities = app.activities;
11467        if (app == mHomeProcess && activities.size() > 0
11468                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11469            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11470                final ActivityRecord r = activities.get(activityNdx);
11471                if (r.isHomeActivity()) {
11472                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11473                    try {
11474                        ActivityThread.getPackageManager()
11475                                .clearPackagePreferredActivities(r.packageName);
11476                    } catch (RemoteException c) {
11477                        // pm is in same process, this will never happen.
11478                    }
11479                }
11480            }
11481        }
11482
11483        if (!app.isolated) {
11484            // XXX Can't keep track of crash times for isolated processes,
11485            // because they don't have a perisistent identity.
11486            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11487        }
11488
11489        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11490        return true;
11491    }
11492
11493    void startAppProblemLocked(ProcessRecord app) {
11494        // If this app is not running under the current user, then we
11495        // can't give it a report button because that would require
11496        // launching the report UI under a different user.
11497        app.errorReportReceiver = null;
11498
11499        for (int userId : mCurrentProfileIds) {
11500            if (app.userId == userId) {
11501                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11502                        mContext, app.info.packageName, app.info.flags);
11503            }
11504        }
11505        skipCurrentReceiverLocked(app);
11506    }
11507
11508    void skipCurrentReceiverLocked(ProcessRecord app) {
11509        for (BroadcastQueue queue : mBroadcastQueues) {
11510            queue.skipCurrentReceiverLocked(app);
11511        }
11512    }
11513
11514    /**
11515     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11516     * The application process will exit immediately after this call returns.
11517     * @param app object of the crashing app, null for the system server
11518     * @param crashInfo describing the exception
11519     */
11520    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11521        ProcessRecord r = findAppProcess(app, "Crash");
11522        final String processName = app == null ? "system_server"
11523                : (r == null ? "unknown" : r.processName);
11524
11525        handleApplicationCrashInner("crash", r, processName, crashInfo);
11526    }
11527
11528    /* Native crash reporting uses this inner version because it needs to be somewhat
11529     * decoupled from the AM-managed cleanup lifecycle
11530     */
11531    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11532            ApplicationErrorReport.CrashInfo crashInfo) {
11533        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11534                UserHandle.getUserId(Binder.getCallingUid()), processName,
11535                r == null ? -1 : r.info.flags,
11536                crashInfo.exceptionClassName,
11537                crashInfo.exceptionMessage,
11538                crashInfo.throwFileName,
11539                crashInfo.throwLineNumber);
11540
11541        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11542
11543        crashApplication(r, crashInfo);
11544    }
11545
11546    public void handleApplicationStrictModeViolation(
11547            IBinder app,
11548            int violationMask,
11549            StrictMode.ViolationInfo info) {
11550        ProcessRecord r = findAppProcess(app, "StrictMode");
11551        if (r == null) {
11552            return;
11553        }
11554
11555        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11556            Integer stackFingerprint = info.hashCode();
11557            boolean logIt = true;
11558            synchronized (mAlreadyLoggedViolatedStacks) {
11559                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11560                    logIt = false;
11561                    // TODO: sub-sample into EventLog for these, with
11562                    // the info.durationMillis?  Then we'd get
11563                    // the relative pain numbers, without logging all
11564                    // the stack traces repeatedly.  We'd want to do
11565                    // likewise in the client code, which also does
11566                    // dup suppression, before the Binder call.
11567                } else {
11568                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11569                        mAlreadyLoggedViolatedStacks.clear();
11570                    }
11571                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11572                }
11573            }
11574            if (logIt) {
11575                logStrictModeViolationToDropBox(r, info);
11576            }
11577        }
11578
11579        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11580            AppErrorResult result = new AppErrorResult();
11581            synchronized (this) {
11582                final long origId = Binder.clearCallingIdentity();
11583
11584                Message msg = Message.obtain();
11585                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11586                HashMap<String, Object> data = new HashMap<String, Object>();
11587                data.put("result", result);
11588                data.put("app", r);
11589                data.put("violationMask", violationMask);
11590                data.put("info", info);
11591                msg.obj = data;
11592                mHandler.sendMessage(msg);
11593
11594                Binder.restoreCallingIdentity(origId);
11595            }
11596            int res = result.get();
11597            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11598        }
11599    }
11600
11601    // Depending on the policy in effect, there could be a bunch of
11602    // these in quick succession so we try to batch these together to
11603    // minimize disk writes, number of dropbox entries, and maximize
11604    // compression, by having more fewer, larger records.
11605    private void logStrictModeViolationToDropBox(
11606            ProcessRecord process,
11607            StrictMode.ViolationInfo info) {
11608        if (info == null) {
11609            return;
11610        }
11611        final boolean isSystemApp = process == null ||
11612                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11613                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11614        final String processName = process == null ? "unknown" : process.processName;
11615        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11616        final DropBoxManager dbox = (DropBoxManager)
11617                mContext.getSystemService(Context.DROPBOX_SERVICE);
11618
11619        // Exit early if the dropbox isn't configured to accept this report type.
11620        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11621
11622        boolean bufferWasEmpty;
11623        boolean needsFlush;
11624        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11625        synchronized (sb) {
11626            bufferWasEmpty = sb.length() == 0;
11627            appendDropBoxProcessHeaders(process, processName, sb);
11628            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11629            sb.append("System-App: ").append(isSystemApp).append("\n");
11630            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11631            if (info.violationNumThisLoop != 0) {
11632                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11633            }
11634            if (info.numAnimationsRunning != 0) {
11635                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11636            }
11637            if (info.broadcastIntentAction != null) {
11638                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11639            }
11640            if (info.durationMillis != -1) {
11641                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11642            }
11643            if (info.numInstances != -1) {
11644                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11645            }
11646            if (info.tags != null) {
11647                for (String tag : info.tags) {
11648                    sb.append("Span-Tag: ").append(tag).append("\n");
11649                }
11650            }
11651            sb.append("\n");
11652            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11653                sb.append(info.crashInfo.stackTrace);
11654            }
11655            sb.append("\n");
11656
11657            // Only buffer up to ~64k.  Various logging bits truncate
11658            // things at 128k.
11659            needsFlush = (sb.length() > 64 * 1024);
11660        }
11661
11662        // Flush immediately if the buffer's grown too large, or this
11663        // is a non-system app.  Non-system apps are isolated with a
11664        // different tag & policy and not batched.
11665        //
11666        // Batching is useful during internal testing with
11667        // StrictMode settings turned up high.  Without batching,
11668        // thousands of separate files could be created on boot.
11669        if (!isSystemApp || needsFlush) {
11670            new Thread("Error dump: " + dropboxTag) {
11671                @Override
11672                public void run() {
11673                    String report;
11674                    synchronized (sb) {
11675                        report = sb.toString();
11676                        sb.delete(0, sb.length());
11677                        sb.trimToSize();
11678                    }
11679                    if (report.length() != 0) {
11680                        dbox.addText(dropboxTag, report);
11681                    }
11682                }
11683            }.start();
11684            return;
11685        }
11686
11687        // System app batching:
11688        if (!bufferWasEmpty) {
11689            // An existing dropbox-writing thread is outstanding, so
11690            // we don't need to start it up.  The existing thread will
11691            // catch the buffer appends we just did.
11692            return;
11693        }
11694
11695        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11696        // (After this point, we shouldn't access AMS internal data structures.)
11697        new Thread("Error dump: " + dropboxTag) {
11698            @Override
11699            public void run() {
11700                // 5 second sleep to let stacks arrive and be batched together
11701                try {
11702                    Thread.sleep(5000);  // 5 seconds
11703                } catch (InterruptedException e) {}
11704
11705                String errorReport;
11706                synchronized (mStrictModeBuffer) {
11707                    errorReport = mStrictModeBuffer.toString();
11708                    if (errorReport.length() == 0) {
11709                        return;
11710                    }
11711                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11712                    mStrictModeBuffer.trimToSize();
11713                }
11714                dbox.addText(dropboxTag, errorReport);
11715            }
11716        }.start();
11717    }
11718
11719    /**
11720     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11721     * @param app object of the crashing app, null for the system server
11722     * @param tag reported by the caller
11723     * @param system whether this wtf is coming from the system
11724     * @param crashInfo describing the context of the error
11725     * @return true if the process should exit immediately (WTF is fatal)
11726     */
11727    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11728            final ApplicationErrorReport.CrashInfo crashInfo) {
11729        final int callingUid = Binder.getCallingUid();
11730        final int callingPid = Binder.getCallingPid();
11731
11732        if (system) {
11733            // If this is coming from the system, we could very well have low-level
11734            // system locks held, so we want to do this all asynchronously.  And we
11735            // never want this to become fatal, so there is that too.
11736            mHandler.post(new Runnable() {
11737                @Override public void run() {
11738                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11739                }
11740            });
11741            return false;
11742        }
11743
11744        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11745                crashInfo);
11746
11747        if (r != null && r.pid != Process.myPid() &&
11748                Settings.Global.getInt(mContext.getContentResolver(),
11749                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11750            crashApplication(r, crashInfo);
11751            return true;
11752        } else {
11753            return false;
11754        }
11755    }
11756
11757    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11758            final ApplicationErrorReport.CrashInfo crashInfo) {
11759        final ProcessRecord r = findAppProcess(app, "WTF");
11760        final String processName = app == null ? "system_server"
11761                : (r == null ? "unknown" : r.processName);
11762
11763        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11764                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11765
11766        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11767
11768        return r;
11769    }
11770
11771    /**
11772     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11773     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11774     */
11775    private ProcessRecord findAppProcess(IBinder app, String reason) {
11776        if (app == null) {
11777            return null;
11778        }
11779
11780        synchronized (this) {
11781            final int NP = mProcessNames.getMap().size();
11782            for (int ip=0; ip<NP; ip++) {
11783                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11784                final int NA = apps.size();
11785                for (int ia=0; ia<NA; ia++) {
11786                    ProcessRecord p = apps.valueAt(ia);
11787                    if (p.thread != null && p.thread.asBinder() == app) {
11788                        return p;
11789                    }
11790                }
11791            }
11792
11793            Slog.w(TAG, "Can't find mystery application for " + reason
11794                    + " from pid=" + Binder.getCallingPid()
11795                    + " uid=" + Binder.getCallingUid() + ": " + app);
11796            return null;
11797        }
11798    }
11799
11800    /**
11801     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11802     * to append various headers to the dropbox log text.
11803     */
11804    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11805            StringBuilder sb) {
11806        // Watchdog thread ends up invoking this function (with
11807        // a null ProcessRecord) to add the stack file to dropbox.
11808        // Do not acquire a lock on this (am) in such cases, as it
11809        // could cause a potential deadlock, if and when watchdog
11810        // is invoked due to unavailability of lock on am and it
11811        // would prevent watchdog from killing system_server.
11812        if (process == null) {
11813            sb.append("Process: ").append(processName).append("\n");
11814            return;
11815        }
11816        // Note: ProcessRecord 'process' is guarded by the service
11817        // instance.  (notably process.pkgList, which could otherwise change
11818        // concurrently during execution of this method)
11819        synchronized (this) {
11820            sb.append("Process: ").append(processName).append("\n");
11821            int flags = process.info.flags;
11822            IPackageManager pm = AppGlobals.getPackageManager();
11823            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11824            for (int ip=0; ip<process.pkgList.size(); ip++) {
11825                String pkg = process.pkgList.keyAt(ip);
11826                sb.append("Package: ").append(pkg);
11827                try {
11828                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11829                    if (pi != null) {
11830                        sb.append(" v").append(pi.versionCode);
11831                        if (pi.versionName != null) {
11832                            sb.append(" (").append(pi.versionName).append(")");
11833                        }
11834                    }
11835                } catch (RemoteException e) {
11836                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11837                }
11838                sb.append("\n");
11839            }
11840        }
11841    }
11842
11843    private static String processClass(ProcessRecord process) {
11844        if (process == null || process.pid == MY_PID) {
11845            return "system_server";
11846        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11847            return "system_app";
11848        } else {
11849            return "data_app";
11850        }
11851    }
11852
11853    /**
11854     * Write a description of an error (crash, WTF, ANR) to the drop box.
11855     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11856     * @param process which caused the error, null means the system server
11857     * @param activity which triggered the error, null if unknown
11858     * @param parent activity related to the error, null if unknown
11859     * @param subject line related to the error, null if absent
11860     * @param report in long form describing the error, null if absent
11861     * @param logFile to include in the report, null if none
11862     * @param crashInfo giving an application stack trace, null if absent
11863     */
11864    public void addErrorToDropBox(String eventType,
11865            ProcessRecord process, String processName, ActivityRecord activity,
11866            ActivityRecord parent, String subject,
11867            final String report, final File logFile,
11868            final ApplicationErrorReport.CrashInfo crashInfo) {
11869        // NOTE -- this must never acquire the ActivityManagerService lock,
11870        // otherwise the watchdog may be prevented from resetting the system.
11871
11872        final String dropboxTag = processClass(process) + "_" + eventType;
11873        final DropBoxManager dbox = (DropBoxManager)
11874                mContext.getSystemService(Context.DROPBOX_SERVICE);
11875
11876        // Exit early if the dropbox isn't configured to accept this report type.
11877        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11878
11879        final StringBuilder sb = new StringBuilder(1024);
11880        appendDropBoxProcessHeaders(process, processName, sb);
11881        if (activity != null) {
11882            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11883        }
11884        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11885            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11886        }
11887        if (parent != null && parent != activity) {
11888            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11889        }
11890        if (subject != null) {
11891            sb.append("Subject: ").append(subject).append("\n");
11892        }
11893        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11894        if (Debug.isDebuggerConnected()) {
11895            sb.append("Debugger: Connected\n");
11896        }
11897        sb.append("\n");
11898
11899        // Do the rest in a worker thread to avoid blocking the caller on I/O
11900        // (After this point, we shouldn't access AMS internal data structures.)
11901        Thread worker = new Thread("Error dump: " + dropboxTag) {
11902            @Override
11903            public void run() {
11904                if (report != null) {
11905                    sb.append(report);
11906                }
11907                if (logFile != null) {
11908                    try {
11909                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11910                                    "\n\n[[TRUNCATED]]"));
11911                    } catch (IOException e) {
11912                        Slog.e(TAG, "Error reading " + logFile, e);
11913                    }
11914                }
11915                if (crashInfo != null && crashInfo.stackTrace != null) {
11916                    sb.append(crashInfo.stackTrace);
11917                }
11918
11919                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11920                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11921                if (lines > 0) {
11922                    sb.append("\n");
11923
11924                    // Merge several logcat streams, and take the last N lines
11925                    InputStreamReader input = null;
11926                    try {
11927                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11928                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11929                                "-b", "crash",
11930                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11931
11932                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11933                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11934                        input = new InputStreamReader(logcat.getInputStream());
11935
11936                        int num;
11937                        char[] buf = new char[8192];
11938                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11939                    } catch (IOException e) {
11940                        Slog.e(TAG, "Error running logcat", e);
11941                    } finally {
11942                        if (input != null) try { input.close(); } catch (IOException e) {}
11943                    }
11944                }
11945
11946                dbox.addText(dropboxTag, sb.toString());
11947            }
11948        };
11949
11950        if (process == null) {
11951            // If process is null, we are being called from some internal code
11952            // and may be about to die -- run this synchronously.
11953            worker.run();
11954        } else {
11955            worker.start();
11956        }
11957    }
11958
11959    /**
11960     * Bring up the "unexpected error" dialog box for a crashing app.
11961     * Deal with edge cases (intercepts from instrumented applications,
11962     * ActivityController, error intent receivers, that sort of thing).
11963     * @param r the application crashing
11964     * @param crashInfo describing the failure
11965     */
11966    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11967        long timeMillis = System.currentTimeMillis();
11968        String shortMsg = crashInfo.exceptionClassName;
11969        String longMsg = crashInfo.exceptionMessage;
11970        String stackTrace = crashInfo.stackTrace;
11971        if (shortMsg != null && longMsg != null) {
11972            longMsg = shortMsg + ": " + longMsg;
11973        } else if (shortMsg != null) {
11974            longMsg = shortMsg;
11975        }
11976
11977        AppErrorResult result = new AppErrorResult();
11978        synchronized (this) {
11979            if (mController != null) {
11980                try {
11981                    String name = r != null ? r.processName : null;
11982                    int pid = r != null ? r.pid : Binder.getCallingPid();
11983                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11984                    if (!mController.appCrashed(name, pid,
11985                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11986                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11987                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11988                            Slog.w(TAG, "Skip killing native crashed app " + name
11989                                    + "(" + pid + ") during testing");
11990                        } else {
11991                            Slog.w(TAG, "Force-killing crashed app " + name
11992                                    + " at watcher's request");
11993                            if (r != null) {
11994                                r.kill("crash", true);
11995                            } else {
11996                                // Huh.
11997                                Process.killProcess(pid);
11998                                Process.killProcessGroup(uid, pid);
11999                            }
12000                        }
12001                        return;
12002                    }
12003                } catch (RemoteException e) {
12004                    mController = null;
12005                    Watchdog.getInstance().setActivityController(null);
12006                }
12007            }
12008
12009            final long origId = Binder.clearCallingIdentity();
12010
12011            // If this process is running instrumentation, finish it.
12012            if (r != null && r.instrumentationClass != null) {
12013                Slog.w(TAG, "Error in app " + r.processName
12014                      + " running instrumentation " + r.instrumentationClass + ":");
12015                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12016                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12017                Bundle info = new Bundle();
12018                info.putString("shortMsg", shortMsg);
12019                info.putString("longMsg", longMsg);
12020                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12021                Binder.restoreCallingIdentity(origId);
12022                return;
12023            }
12024
12025            // If we can't identify the process or it's already exceeded its crash quota,
12026            // quit right away without showing a crash dialog.
12027            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12028                Binder.restoreCallingIdentity(origId);
12029                return;
12030            }
12031
12032            Message msg = Message.obtain();
12033            msg.what = SHOW_ERROR_MSG;
12034            HashMap data = new HashMap();
12035            data.put("result", result);
12036            data.put("app", r);
12037            msg.obj = data;
12038            mHandler.sendMessage(msg);
12039
12040            Binder.restoreCallingIdentity(origId);
12041        }
12042
12043        int res = result.get();
12044
12045        Intent appErrorIntent = null;
12046        synchronized (this) {
12047            if (r != null && !r.isolated) {
12048                // XXX Can't keep track of crash time for isolated processes,
12049                // since they don't have a persistent identity.
12050                mProcessCrashTimes.put(r.info.processName, r.uid,
12051                        SystemClock.uptimeMillis());
12052            }
12053            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12054                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12055            }
12056        }
12057
12058        if (appErrorIntent != null) {
12059            try {
12060                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12061            } catch (ActivityNotFoundException e) {
12062                Slog.w(TAG, "bug report receiver dissappeared", e);
12063            }
12064        }
12065    }
12066
12067    Intent createAppErrorIntentLocked(ProcessRecord r,
12068            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12069        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12070        if (report == null) {
12071            return null;
12072        }
12073        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12074        result.setComponent(r.errorReportReceiver);
12075        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12076        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12077        return result;
12078    }
12079
12080    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12081            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12082        if (r.errorReportReceiver == null) {
12083            return null;
12084        }
12085
12086        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12087            return null;
12088        }
12089
12090        ApplicationErrorReport report = new ApplicationErrorReport();
12091        report.packageName = r.info.packageName;
12092        report.installerPackageName = r.errorReportReceiver.getPackageName();
12093        report.processName = r.processName;
12094        report.time = timeMillis;
12095        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12096
12097        if (r.crashing || r.forceCrashReport) {
12098            report.type = ApplicationErrorReport.TYPE_CRASH;
12099            report.crashInfo = crashInfo;
12100        } else if (r.notResponding) {
12101            report.type = ApplicationErrorReport.TYPE_ANR;
12102            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12103
12104            report.anrInfo.activity = r.notRespondingReport.tag;
12105            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12106            report.anrInfo.info = r.notRespondingReport.longMsg;
12107        }
12108
12109        return report;
12110    }
12111
12112    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12113        enforceNotIsolatedCaller("getProcessesInErrorState");
12114        // assume our apps are happy - lazy create the list
12115        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12116
12117        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12118                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12119        int userId = UserHandle.getUserId(Binder.getCallingUid());
12120
12121        synchronized (this) {
12122
12123            // iterate across all processes
12124            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12125                ProcessRecord app = mLruProcesses.get(i);
12126                if (!allUsers && app.userId != userId) {
12127                    continue;
12128                }
12129                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12130                    // This one's in trouble, so we'll generate a report for it
12131                    // crashes are higher priority (in case there's a crash *and* an anr)
12132                    ActivityManager.ProcessErrorStateInfo report = null;
12133                    if (app.crashing) {
12134                        report = app.crashingReport;
12135                    } else if (app.notResponding) {
12136                        report = app.notRespondingReport;
12137                    }
12138
12139                    if (report != null) {
12140                        if (errList == null) {
12141                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12142                        }
12143                        errList.add(report);
12144                    } else {
12145                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12146                                " crashing = " + app.crashing +
12147                                " notResponding = " + app.notResponding);
12148                    }
12149                }
12150            }
12151        }
12152
12153        return errList;
12154    }
12155
12156    static int procStateToImportance(int procState, int memAdj,
12157            ActivityManager.RunningAppProcessInfo currApp) {
12158        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12159        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12160            currApp.lru = memAdj;
12161        } else {
12162            currApp.lru = 0;
12163        }
12164        return imp;
12165    }
12166
12167    private void fillInProcMemInfo(ProcessRecord app,
12168            ActivityManager.RunningAppProcessInfo outInfo) {
12169        outInfo.pid = app.pid;
12170        outInfo.uid = app.info.uid;
12171        if (mHeavyWeightProcess == app) {
12172            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12173        }
12174        if (app.persistent) {
12175            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12176        }
12177        if (app.activities.size() > 0) {
12178            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12179        }
12180        outInfo.lastTrimLevel = app.trimMemoryLevel;
12181        int adj = app.curAdj;
12182        int procState = app.curProcState;
12183        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12184        outInfo.importanceReasonCode = app.adjTypeCode;
12185        outInfo.processState = app.curProcState;
12186    }
12187
12188    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12189        enforceNotIsolatedCaller("getRunningAppProcesses");
12190        // Lazy instantiation of list
12191        List<ActivityManager.RunningAppProcessInfo> runList = null;
12192        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12193                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12194        int userId = UserHandle.getUserId(Binder.getCallingUid());
12195        synchronized (this) {
12196            // Iterate across all processes
12197            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12198                ProcessRecord app = mLruProcesses.get(i);
12199                if (!allUsers && app.userId != userId) {
12200                    continue;
12201                }
12202                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12203                    // Generate process state info for running application
12204                    ActivityManager.RunningAppProcessInfo currApp =
12205                        new ActivityManager.RunningAppProcessInfo(app.processName,
12206                                app.pid, app.getPackageList());
12207                    fillInProcMemInfo(app, currApp);
12208                    if (app.adjSource instanceof ProcessRecord) {
12209                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12210                        currApp.importanceReasonImportance =
12211                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12212                                        app.adjSourceProcState);
12213                    } else if (app.adjSource instanceof ActivityRecord) {
12214                        ActivityRecord r = (ActivityRecord)app.adjSource;
12215                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12216                    }
12217                    if (app.adjTarget instanceof ComponentName) {
12218                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12219                    }
12220                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12221                    //        + " lru=" + currApp.lru);
12222                    if (runList == null) {
12223                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12224                    }
12225                    runList.add(currApp);
12226                }
12227            }
12228        }
12229        return runList;
12230    }
12231
12232    public List<ApplicationInfo> getRunningExternalApplications() {
12233        enforceNotIsolatedCaller("getRunningExternalApplications");
12234        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12235        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12236        if (runningApps != null && runningApps.size() > 0) {
12237            Set<String> extList = new HashSet<String>();
12238            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12239                if (app.pkgList != null) {
12240                    for (String pkg : app.pkgList) {
12241                        extList.add(pkg);
12242                    }
12243                }
12244            }
12245            IPackageManager pm = AppGlobals.getPackageManager();
12246            for (String pkg : extList) {
12247                try {
12248                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12249                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12250                        retList.add(info);
12251                    }
12252                } catch (RemoteException e) {
12253                }
12254            }
12255        }
12256        return retList;
12257    }
12258
12259    @Override
12260    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12261        enforceNotIsolatedCaller("getMyMemoryState");
12262        synchronized (this) {
12263            ProcessRecord proc;
12264            synchronized (mPidsSelfLocked) {
12265                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12266            }
12267            fillInProcMemInfo(proc, outInfo);
12268        }
12269    }
12270
12271    @Override
12272    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12273        if (checkCallingPermission(android.Manifest.permission.DUMP)
12274                != PackageManager.PERMISSION_GRANTED) {
12275            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12276                    + Binder.getCallingPid()
12277                    + ", uid=" + Binder.getCallingUid()
12278                    + " without permission "
12279                    + android.Manifest.permission.DUMP);
12280            return;
12281        }
12282
12283        boolean dumpAll = false;
12284        boolean dumpClient = false;
12285        String dumpPackage = null;
12286
12287        int opti = 0;
12288        while (opti < args.length) {
12289            String opt = args[opti];
12290            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12291                break;
12292            }
12293            opti++;
12294            if ("-a".equals(opt)) {
12295                dumpAll = true;
12296            } else if ("-c".equals(opt)) {
12297                dumpClient = true;
12298            } else if ("-h".equals(opt)) {
12299                pw.println("Activity manager dump options:");
12300                pw.println("  [-a] [-c] [-h] [cmd] ...");
12301                pw.println("  cmd may be one of:");
12302                pw.println("    a[ctivities]: activity stack state");
12303                pw.println("    r[recents]: recent activities state");
12304                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12305                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12306                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12307                pw.println("    o[om]: out of memory management");
12308                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12309                pw.println("    provider [COMP_SPEC]: provider client-side state");
12310                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12311                pw.println("    service [COMP_SPEC]: service client-side state");
12312                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12313                pw.println("    all: dump all activities");
12314                pw.println("    top: dump the top activity");
12315                pw.println("    write: write all pending state to storage");
12316                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12317                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12318                pw.println("    a partial substring in a component name, a");
12319                pw.println("    hex object identifier.");
12320                pw.println("  -a: include all available server state.");
12321                pw.println("  -c: include client state.");
12322                return;
12323            } else {
12324                pw.println("Unknown argument: " + opt + "; use -h for help");
12325            }
12326        }
12327
12328        long origId = Binder.clearCallingIdentity();
12329        boolean more = false;
12330        // Is the caller requesting to dump a particular piece of data?
12331        if (opti < args.length) {
12332            String cmd = args[opti];
12333            opti++;
12334            if ("activities".equals(cmd) || "a".equals(cmd)) {
12335                synchronized (this) {
12336                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12337                }
12338            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12339                synchronized (this) {
12340                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12341                }
12342            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12343                String[] newArgs;
12344                String name;
12345                if (opti >= args.length) {
12346                    name = null;
12347                    newArgs = EMPTY_STRING_ARRAY;
12348                } else {
12349                    name = args[opti];
12350                    opti++;
12351                    newArgs = new String[args.length - opti];
12352                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12353                            args.length - opti);
12354                }
12355                synchronized (this) {
12356                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12357                }
12358            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12359                String[] newArgs;
12360                String name;
12361                if (opti >= args.length) {
12362                    name = null;
12363                    newArgs = EMPTY_STRING_ARRAY;
12364                } else {
12365                    name = args[opti];
12366                    opti++;
12367                    newArgs = new String[args.length - opti];
12368                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12369                            args.length - opti);
12370                }
12371                synchronized (this) {
12372                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12373                }
12374            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12375                String[] newArgs;
12376                String name;
12377                if (opti >= args.length) {
12378                    name = null;
12379                    newArgs = EMPTY_STRING_ARRAY;
12380                } else {
12381                    name = args[opti];
12382                    opti++;
12383                    newArgs = new String[args.length - opti];
12384                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12385                            args.length - opti);
12386                }
12387                synchronized (this) {
12388                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12389                }
12390            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12391                synchronized (this) {
12392                    dumpOomLocked(fd, pw, args, opti, true);
12393                }
12394            } else if ("provider".equals(cmd)) {
12395                String[] newArgs;
12396                String name;
12397                if (opti >= args.length) {
12398                    name = null;
12399                    newArgs = EMPTY_STRING_ARRAY;
12400                } else {
12401                    name = args[opti];
12402                    opti++;
12403                    newArgs = new String[args.length - opti];
12404                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12405                }
12406                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12407                    pw.println("No providers match: " + name);
12408                    pw.println("Use -h for help.");
12409                }
12410            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12411                synchronized (this) {
12412                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12413                }
12414            } else if ("service".equals(cmd)) {
12415                String[] newArgs;
12416                String name;
12417                if (opti >= args.length) {
12418                    name = null;
12419                    newArgs = EMPTY_STRING_ARRAY;
12420                } else {
12421                    name = args[opti];
12422                    opti++;
12423                    newArgs = new String[args.length - opti];
12424                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12425                            args.length - opti);
12426                }
12427                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12428                    pw.println("No services match: " + name);
12429                    pw.println("Use -h for help.");
12430                }
12431            } else if ("package".equals(cmd)) {
12432                String[] newArgs;
12433                if (opti >= args.length) {
12434                    pw.println("package: no package name specified");
12435                    pw.println("Use -h for help.");
12436                } else {
12437                    dumpPackage = args[opti];
12438                    opti++;
12439                    newArgs = new String[args.length - opti];
12440                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12441                            args.length - opti);
12442                    args = newArgs;
12443                    opti = 0;
12444                    more = true;
12445                }
12446            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12447                synchronized (this) {
12448                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12449                }
12450            } else if ("write".equals(cmd)) {
12451                mTaskPersister.flush();
12452                pw.println("All tasks persisted.");
12453                return;
12454            } else {
12455                // Dumping a single activity?
12456                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12457                    pw.println("Bad activity command, or no activities match: " + cmd);
12458                    pw.println("Use -h for help.");
12459                }
12460            }
12461            if (!more) {
12462                Binder.restoreCallingIdentity(origId);
12463                return;
12464            }
12465        }
12466
12467        // No piece of data specified, dump everything.
12468        synchronized (this) {
12469            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12470            pw.println();
12471            if (dumpAll) {
12472                pw.println("-------------------------------------------------------------------------------");
12473            }
12474            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12475            pw.println();
12476            if (dumpAll) {
12477                pw.println("-------------------------------------------------------------------------------");
12478            }
12479            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12480            pw.println();
12481            if (dumpAll) {
12482                pw.println("-------------------------------------------------------------------------------");
12483            }
12484            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12485            pw.println();
12486            if (dumpAll) {
12487                pw.println("-------------------------------------------------------------------------------");
12488            }
12489            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12490            pw.println();
12491            if (dumpAll) {
12492                pw.println("-------------------------------------------------------------------------------");
12493            }
12494            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12495            pw.println();
12496            if (dumpAll) {
12497                pw.println("-------------------------------------------------------------------------------");
12498            }
12499            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12500        }
12501        Binder.restoreCallingIdentity(origId);
12502    }
12503
12504    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12505            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12506        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12507
12508        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12509                dumpPackage);
12510        boolean needSep = printedAnything;
12511
12512        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12513                dumpPackage, needSep, "  mFocusedActivity: ");
12514        if (printed) {
12515            printedAnything = true;
12516            needSep = false;
12517        }
12518
12519        if (dumpPackage == null) {
12520            if (needSep) {
12521                pw.println();
12522            }
12523            needSep = true;
12524            printedAnything = true;
12525            mStackSupervisor.dump(pw, "  ");
12526        }
12527
12528        if (!printedAnything) {
12529            pw.println("  (nothing)");
12530        }
12531    }
12532
12533    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12534            int opti, boolean dumpAll, String dumpPackage) {
12535        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12536
12537        boolean printedAnything = false;
12538
12539        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12540            boolean printedHeader = false;
12541
12542            final int N = mRecentTasks.size();
12543            for (int i=0; i<N; i++) {
12544                TaskRecord tr = mRecentTasks.get(i);
12545                if (dumpPackage != null) {
12546                    if (tr.realActivity == null ||
12547                            !dumpPackage.equals(tr.realActivity)) {
12548                        continue;
12549                    }
12550                }
12551                if (!printedHeader) {
12552                    pw.println("  Recent tasks:");
12553                    printedHeader = true;
12554                    printedAnything = true;
12555                }
12556                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12557                        pw.println(tr);
12558                if (dumpAll) {
12559                    mRecentTasks.get(i).dump(pw, "    ");
12560                }
12561            }
12562        }
12563
12564        if (!printedAnything) {
12565            pw.println("  (nothing)");
12566        }
12567    }
12568
12569    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12570            int opti, boolean dumpAll, String dumpPackage) {
12571        boolean needSep = false;
12572        boolean printedAnything = false;
12573        int numPers = 0;
12574
12575        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12576
12577        if (dumpAll) {
12578            final int NP = mProcessNames.getMap().size();
12579            for (int ip=0; ip<NP; ip++) {
12580                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12581                final int NA = procs.size();
12582                for (int ia=0; ia<NA; ia++) {
12583                    ProcessRecord r = procs.valueAt(ia);
12584                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12585                        continue;
12586                    }
12587                    if (!needSep) {
12588                        pw.println("  All known processes:");
12589                        needSep = true;
12590                        printedAnything = true;
12591                    }
12592                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12593                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12594                        pw.print(" "); pw.println(r);
12595                    r.dump(pw, "    ");
12596                    if (r.persistent) {
12597                        numPers++;
12598                    }
12599                }
12600            }
12601        }
12602
12603        if (mIsolatedProcesses.size() > 0) {
12604            boolean printed = false;
12605            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12606                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12607                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12608                    continue;
12609                }
12610                if (!printed) {
12611                    if (needSep) {
12612                        pw.println();
12613                    }
12614                    pw.println("  Isolated process list (sorted by uid):");
12615                    printedAnything = true;
12616                    printed = true;
12617                    needSep = true;
12618                }
12619                pw.println(String.format("%sIsolated #%2d: %s",
12620                        "    ", i, r.toString()));
12621            }
12622        }
12623
12624        if (mLruProcesses.size() > 0) {
12625            if (needSep) {
12626                pw.println();
12627            }
12628            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12629                    pw.print(" total, non-act at ");
12630                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12631                    pw.print(", non-svc at ");
12632                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12633                    pw.println("):");
12634            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12635            needSep = true;
12636            printedAnything = true;
12637        }
12638
12639        if (dumpAll || dumpPackage != null) {
12640            synchronized (mPidsSelfLocked) {
12641                boolean printed = false;
12642                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12643                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12644                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12645                        continue;
12646                    }
12647                    if (!printed) {
12648                        if (needSep) pw.println();
12649                        needSep = true;
12650                        pw.println("  PID mappings:");
12651                        printed = true;
12652                        printedAnything = true;
12653                    }
12654                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12655                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12656                }
12657            }
12658        }
12659
12660        if (mForegroundProcesses.size() > 0) {
12661            synchronized (mPidsSelfLocked) {
12662                boolean printed = false;
12663                for (int i=0; i<mForegroundProcesses.size(); i++) {
12664                    ProcessRecord r = mPidsSelfLocked.get(
12665                            mForegroundProcesses.valueAt(i).pid);
12666                    if (dumpPackage != null && (r == null
12667                            || !r.pkgList.containsKey(dumpPackage))) {
12668                        continue;
12669                    }
12670                    if (!printed) {
12671                        if (needSep) pw.println();
12672                        needSep = true;
12673                        pw.println("  Foreground Processes:");
12674                        printed = true;
12675                        printedAnything = true;
12676                    }
12677                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12678                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12679                }
12680            }
12681        }
12682
12683        if (mPersistentStartingProcesses.size() > 0) {
12684            if (needSep) pw.println();
12685            needSep = true;
12686            printedAnything = true;
12687            pw.println("  Persisent processes that are starting:");
12688            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12689                    "Starting Norm", "Restarting PERS", dumpPackage);
12690        }
12691
12692        if (mRemovedProcesses.size() > 0) {
12693            if (needSep) pw.println();
12694            needSep = true;
12695            printedAnything = true;
12696            pw.println("  Processes that are being removed:");
12697            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12698                    "Removed Norm", "Removed PERS", dumpPackage);
12699        }
12700
12701        if (mProcessesOnHold.size() > 0) {
12702            if (needSep) pw.println();
12703            needSep = true;
12704            printedAnything = true;
12705            pw.println("  Processes that are on old until the system is ready:");
12706            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12707                    "OnHold Norm", "OnHold PERS", dumpPackage);
12708        }
12709
12710        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12711
12712        if (mProcessCrashTimes.getMap().size() > 0) {
12713            boolean printed = false;
12714            long now = SystemClock.uptimeMillis();
12715            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12716            final int NP = pmap.size();
12717            for (int ip=0; ip<NP; ip++) {
12718                String pname = pmap.keyAt(ip);
12719                SparseArray<Long> uids = pmap.valueAt(ip);
12720                final int N = uids.size();
12721                for (int i=0; i<N; i++) {
12722                    int puid = uids.keyAt(i);
12723                    ProcessRecord r = mProcessNames.get(pname, puid);
12724                    if (dumpPackage != null && (r == null
12725                            || !r.pkgList.containsKey(dumpPackage))) {
12726                        continue;
12727                    }
12728                    if (!printed) {
12729                        if (needSep) pw.println();
12730                        needSep = true;
12731                        pw.println("  Time since processes crashed:");
12732                        printed = true;
12733                        printedAnything = true;
12734                    }
12735                    pw.print("    Process "); pw.print(pname);
12736                            pw.print(" uid "); pw.print(puid);
12737                            pw.print(": last crashed ");
12738                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12739                            pw.println(" ago");
12740                }
12741            }
12742        }
12743
12744        if (mBadProcesses.getMap().size() > 0) {
12745            boolean printed = false;
12746            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12747            final int NP = pmap.size();
12748            for (int ip=0; ip<NP; ip++) {
12749                String pname = pmap.keyAt(ip);
12750                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12751                final int N = uids.size();
12752                for (int i=0; i<N; i++) {
12753                    int puid = uids.keyAt(i);
12754                    ProcessRecord r = mProcessNames.get(pname, puid);
12755                    if (dumpPackage != null && (r == null
12756                            || !r.pkgList.containsKey(dumpPackage))) {
12757                        continue;
12758                    }
12759                    if (!printed) {
12760                        if (needSep) pw.println();
12761                        needSep = true;
12762                        pw.println("  Bad processes:");
12763                        printedAnything = true;
12764                    }
12765                    BadProcessInfo info = uids.valueAt(i);
12766                    pw.print("    Bad process "); pw.print(pname);
12767                            pw.print(" uid "); pw.print(puid);
12768                            pw.print(": crashed at time "); pw.println(info.time);
12769                    if (info.shortMsg != null) {
12770                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12771                    }
12772                    if (info.longMsg != null) {
12773                        pw.print("      Long msg: "); pw.println(info.longMsg);
12774                    }
12775                    if (info.stack != null) {
12776                        pw.println("      Stack:");
12777                        int lastPos = 0;
12778                        for (int pos=0; pos<info.stack.length(); pos++) {
12779                            if (info.stack.charAt(pos) == '\n') {
12780                                pw.print("        ");
12781                                pw.write(info.stack, lastPos, pos-lastPos);
12782                                pw.println();
12783                                lastPos = pos+1;
12784                            }
12785                        }
12786                        if (lastPos < info.stack.length()) {
12787                            pw.print("        ");
12788                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12789                            pw.println();
12790                        }
12791                    }
12792                }
12793            }
12794        }
12795
12796        if (dumpPackage == null) {
12797            pw.println();
12798            needSep = false;
12799            pw.println("  mStartedUsers:");
12800            for (int i=0; i<mStartedUsers.size(); i++) {
12801                UserStartedState uss = mStartedUsers.valueAt(i);
12802                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12803                        pw.print(": "); uss.dump("", pw);
12804            }
12805            pw.print("  mStartedUserArray: [");
12806            for (int i=0; i<mStartedUserArray.length; i++) {
12807                if (i > 0) pw.print(", ");
12808                pw.print(mStartedUserArray[i]);
12809            }
12810            pw.println("]");
12811            pw.print("  mUserLru: [");
12812            for (int i=0; i<mUserLru.size(); i++) {
12813                if (i > 0) pw.print(", ");
12814                pw.print(mUserLru.get(i));
12815            }
12816            pw.println("]");
12817            if (dumpAll) {
12818                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12819            }
12820            synchronized (mUserProfileGroupIdsSelfLocked) {
12821                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12822                    pw.println("  mUserProfileGroupIds:");
12823                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12824                        pw.print("    User #");
12825                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12826                        pw.print(" -> profile #");
12827                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12828                    }
12829                }
12830            }
12831        }
12832        if (mHomeProcess != null && (dumpPackage == null
12833                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12834            if (needSep) {
12835                pw.println();
12836                needSep = false;
12837            }
12838            pw.println("  mHomeProcess: " + mHomeProcess);
12839        }
12840        if (mPreviousProcess != null && (dumpPackage == null
12841                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12842            if (needSep) {
12843                pw.println();
12844                needSep = false;
12845            }
12846            pw.println("  mPreviousProcess: " + mPreviousProcess);
12847        }
12848        if (dumpAll) {
12849            StringBuilder sb = new StringBuilder(128);
12850            sb.append("  mPreviousProcessVisibleTime: ");
12851            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12852            pw.println(sb);
12853        }
12854        if (mHeavyWeightProcess != null && (dumpPackage == null
12855                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12856            if (needSep) {
12857                pw.println();
12858                needSep = false;
12859            }
12860            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12861        }
12862        if (dumpPackage == null) {
12863            pw.println("  mConfiguration: " + mConfiguration);
12864        }
12865        if (dumpAll) {
12866            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12867            if (mCompatModePackages.getPackages().size() > 0) {
12868                boolean printed = false;
12869                for (Map.Entry<String, Integer> entry
12870                        : mCompatModePackages.getPackages().entrySet()) {
12871                    String pkg = entry.getKey();
12872                    int mode = entry.getValue();
12873                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12874                        continue;
12875                    }
12876                    if (!printed) {
12877                        pw.println("  mScreenCompatPackages:");
12878                        printed = true;
12879                    }
12880                    pw.print("    "); pw.print(pkg); pw.print(": ");
12881                            pw.print(mode); pw.println();
12882                }
12883            }
12884        }
12885        if (dumpPackage == null) {
12886            pw.println("  mWakefulness="
12887                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12888            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12889                    + lockScreenShownToString());
12890            pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12891        }
12892        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12893                || mOrigWaitForDebugger) {
12894            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12895                    || dumpPackage.equals(mOrigDebugApp)) {
12896                if (needSep) {
12897                    pw.println();
12898                    needSep = false;
12899                }
12900                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12901                        + " mDebugTransient=" + mDebugTransient
12902                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12903            }
12904        }
12905        if (mOpenGlTraceApp != null) {
12906            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12907                if (needSep) {
12908                    pw.println();
12909                    needSep = false;
12910                }
12911                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12912            }
12913        }
12914        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12915                || mProfileFd != null) {
12916            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12917                if (needSep) {
12918                    pw.println();
12919                    needSep = false;
12920                }
12921                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12922                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12923                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12924                        + mAutoStopProfiler);
12925                pw.println("  mProfileType=" + mProfileType);
12926            }
12927        }
12928        if (dumpPackage == null) {
12929            if (mAlwaysFinishActivities || mController != null) {
12930                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12931                        + " mController=" + mController);
12932            }
12933            if (dumpAll) {
12934                pw.println("  Total persistent processes: " + numPers);
12935                pw.println("  mProcessesReady=" + mProcessesReady
12936                        + " mSystemReady=" + mSystemReady
12937                        + " mBooted=" + mBooted
12938                        + " mFactoryTest=" + mFactoryTest);
12939                pw.println("  mBooting=" + mBooting
12940                        + " mCallFinishBooting=" + mCallFinishBooting
12941                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12942                pw.print("  mLastPowerCheckRealtime=");
12943                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12944                        pw.println("");
12945                pw.print("  mLastPowerCheckUptime=");
12946                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12947                        pw.println("");
12948                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12949                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12950                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12951                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12952                        + " (" + mLruProcesses.size() + " total)"
12953                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12954                        + " mNumServiceProcs=" + mNumServiceProcs
12955                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12956                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12957                        + " mLastMemoryLevel" + mLastMemoryLevel
12958                        + " mLastNumProcesses" + mLastNumProcesses);
12959                long now = SystemClock.uptimeMillis();
12960                pw.print("  mLastIdleTime=");
12961                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12962                        pw.print(" mLowRamSinceLastIdle=");
12963                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12964                        pw.println();
12965            }
12966        }
12967
12968        if (!printedAnything) {
12969            pw.println("  (nothing)");
12970        }
12971    }
12972
12973    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12974            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12975        if (mProcessesToGc.size() > 0) {
12976            boolean printed = false;
12977            long now = SystemClock.uptimeMillis();
12978            for (int i=0; i<mProcessesToGc.size(); i++) {
12979                ProcessRecord proc = mProcessesToGc.get(i);
12980                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12981                    continue;
12982                }
12983                if (!printed) {
12984                    if (needSep) pw.println();
12985                    needSep = true;
12986                    pw.println("  Processes that are waiting to GC:");
12987                    printed = true;
12988                }
12989                pw.print("    Process "); pw.println(proc);
12990                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12991                        pw.print(", last gced=");
12992                        pw.print(now-proc.lastRequestedGc);
12993                        pw.print(" ms ago, last lowMem=");
12994                        pw.print(now-proc.lastLowMemory);
12995                        pw.println(" ms ago");
12996
12997            }
12998        }
12999        return needSep;
13000    }
13001
13002    void printOomLevel(PrintWriter pw, String name, int adj) {
13003        pw.print("    ");
13004        if (adj >= 0) {
13005            pw.print(' ');
13006            if (adj < 10) pw.print(' ');
13007        } else {
13008            if (adj > -10) pw.print(' ');
13009        }
13010        pw.print(adj);
13011        pw.print(": ");
13012        pw.print(name);
13013        pw.print(" (");
13014        pw.print(mProcessList.getMemLevel(adj)/1024);
13015        pw.println(" kB)");
13016    }
13017
13018    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13019            int opti, boolean dumpAll) {
13020        boolean needSep = false;
13021
13022        if (mLruProcesses.size() > 0) {
13023            if (needSep) pw.println();
13024            needSep = true;
13025            pw.println("  OOM levels:");
13026            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13027            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13028            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13029            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13030            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13031            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13032            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13033            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13034            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13035            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13036            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13037            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13038            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13039            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13040
13041            if (needSep) pw.println();
13042            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13043                    pw.print(" total, non-act at ");
13044                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13045                    pw.print(", non-svc at ");
13046                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13047                    pw.println("):");
13048            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13049            needSep = true;
13050        }
13051
13052        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13053
13054        pw.println();
13055        pw.println("  mHomeProcess: " + mHomeProcess);
13056        pw.println("  mPreviousProcess: " + mPreviousProcess);
13057        if (mHeavyWeightProcess != null) {
13058            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13059        }
13060
13061        return true;
13062    }
13063
13064    /**
13065     * There are three ways to call this:
13066     *  - no provider specified: dump all the providers
13067     *  - a flattened component name that matched an existing provider was specified as the
13068     *    first arg: dump that one provider
13069     *  - the first arg isn't the flattened component name of an existing provider:
13070     *    dump all providers whose component contains the first arg as a substring
13071     */
13072    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13073            int opti, boolean dumpAll) {
13074        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13075    }
13076
13077    static class ItemMatcher {
13078        ArrayList<ComponentName> components;
13079        ArrayList<String> strings;
13080        ArrayList<Integer> objects;
13081        boolean all;
13082
13083        ItemMatcher() {
13084            all = true;
13085        }
13086
13087        void build(String name) {
13088            ComponentName componentName = ComponentName.unflattenFromString(name);
13089            if (componentName != null) {
13090                if (components == null) {
13091                    components = new ArrayList<ComponentName>();
13092                }
13093                components.add(componentName);
13094                all = false;
13095            } else {
13096                int objectId = 0;
13097                // Not a '/' separated full component name; maybe an object ID?
13098                try {
13099                    objectId = Integer.parseInt(name, 16);
13100                    if (objects == null) {
13101                        objects = new ArrayList<Integer>();
13102                    }
13103                    objects.add(objectId);
13104                    all = false;
13105                } catch (RuntimeException e) {
13106                    // Not an integer; just do string match.
13107                    if (strings == null) {
13108                        strings = new ArrayList<String>();
13109                    }
13110                    strings.add(name);
13111                    all = false;
13112                }
13113            }
13114        }
13115
13116        int build(String[] args, int opti) {
13117            for (; opti<args.length; opti++) {
13118                String name = args[opti];
13119                if ("--".equals(name)) {
13120                    return opti+1;
13121                }
13122                build(name);
13123            }
13124            return opti;
13125        }
13126
13127        boolean match(Object object, ComponentName comp) {
13128            if (all) {
13129                return true;
13130            }
13131            if (components != null) {
13132                for (int i=0; i<components.size(); i++) {
13133                    if (components.get(i).equals(comp)) {
13134                        return true;
13135                    }
13136                }
13137            }
13138            if (objects != null) {
13139                for (int i=0; i<objects.size(); i++) {
13140                    if (System.identityHashCode(object) == objects.get(i)) {
13141                        return true;
13142                    }
13143                }
13144            }
13145            if (strings != null) {
13146                String flat = comp.flattenToString();
13147                for (int i=0; i<strings.size(); i++) {
13148                    if (flat.contains(strings.get(i))) {
13149                        return true;
13150                    }
13151                }
13152            }
13153            return false;
13154        }
13155    }
13156
13157    /**
13158     * There are three things that cmd can be:
13159     *  - a flattened component name that matches an existing activity
13160     *  - the cmd arg isn't the flattened component name of an existing activity:
13161     *    dump all activity whose component contains the cmd as a substring
13162     *  - A hex number of the ActivityRecord object instance.
13163     */
13164    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13165            int opti, boolean dumpAll) {
13166        ArrayList<ActivityRecord> activities;
13167
13168        synchronized (this) {
13169            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13170        }
13171
13172        if (activities.size() <= 0) {
13173            return false;
13174        }
13175
13176        String[] newArgs = new String[args.length - opti];
13177        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13178
13179        TaskRecord lastTask = null;
13180        boolean needSep = false;
13181        for (int i=activities.size()-1; i>=0; i--) {
13182            ActivityRecord r = activities.get(i);
13183            if (needSep) {
13184                pw.println();
13185            }
13186            needSep = true;
13187            synchronized (this) {
13188                if (lastTask != r.task) {
13189                    lastTask = r.task;
13190                    pw.print("TASK "); pw.print(lastTask.affinity);
13191                            pw.print(" id="); pw.println(lastTask.taskId);
13192                    if (dumpAll) {
13193                        lastTask.dump(pw, "  ");
13194                    }
13195                }
13196            }
13197            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13198        }
13199        return true;
13200    }
13201
13202    /**
13203     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13204     * there is a thread associated with the activity.
13205     */
13206    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13207            final ActivityRecord r, String[] args, boolean dumpAll) {
13208        String innerPrefix = prefix + "  ";
13209        synchronized (this) {
13210            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13211                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13212                    pw.print(" pid=");
13213                    if (r.app != null) pw.println(r.app.pid);
13214                    else pw.println("(not running)");
13215            if (dumpAll) {
13216                r.dump(pw, innerPrefix);
13217            }
13218        }
13219        if (r.app != null && r.app.thread != null) {
13220            // flush anything that is already in the PrintWriter since the thread is going
13221            // to write to the file descriptor directly
13222            pw.flush();
13223            try {
13224                TransferPipe tp = new TransferPipe();
13225                try {
13226                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13227                            r.appToken, innerPrefix, args);
13228                    tp.go(fd);
13229                } finally {
13230                    tp.kill();
13231                }
13232            } catch (IOException e) {
13233                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13234            } catch (RemoteException e) {
13235                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13236            }
13237        }
13238    }
13239
13240    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13241            int opti, boolean dumpAll, String dumpPackage) {
13242        boolean needSep = false;
13243        boolean onlyHistory = false;
13244        boolean printedAnything = false;
13245
13246        if ("history".equals(dumpPackage)) {
13247            if (opti < args.length && "-s".equals(args[opti])) {
13248                dumpAll = false;
13249            }
13250            onlyHistory = true;
13251            dumpPackage = null;
13252        }
13253
13254        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13255        if (!onlyHistory && dumpAll) {
13256            if (mRegisteredReceivers.size() > 0) {
13257                boolean printed = false;
13258                Iterator it = mRegisteredReceivers.values().iterator();
13259                while (it.hasNext()) {
13260                    ReceiverList r = (ReceiverList)it.next();
13261                    if (dumpPackage != null && (r.app == null ||
13262                            !dumpPackage.equals(r.app.info.packageName))) {
13263                        continue;
13264                    }
13265                    if (!printed) {
13266                        pw.println("  Registered Receivers:");
13267                        needSep = true;
13268                        printed = true;
13269                        printedAnything = true;
13270                    }
13271                    pw.print("  * "); pw.println(r);
13272                    r.dump(pw, "    ");
13273                }
13274            }
13275
13276            if (mReceiverResolver.dump(pw, needSep ?
13277                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13278                    "    ", dumpPackage, false, false)) {
13279                needSep = true;
13280                printedAnything = true;
13281            }
13282        }
13283
13284        for (BroadcastQueue q : mBroadcastQueues) {
13285            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13286            printedAnything |= needSep;
13287        }
13288
13289        needSep = true;
13290
13291        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13292            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13293                if (needSep) {
13294                    pw.println();
13295                }
13296                needSep = true;
13297                printedAnything = true;
13298                pw.print("  Sticky broadcasts for user ");
13299                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13300                StringBuilder sb = new StringBuilder(128);
13301                for (Map.Entry<String, ArrayList<Intent>> ent
13302                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13303                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13304                    if (dumpAll) {
13305                        pw.println(":");
13306                        ArrayList<Intent> intents = ent.getValue();
13307                        final int N = intents.size();
13308                        for (int i=0; i<N; i++) {
13309                            sb.setLength(0);
13310                            sb.append("    Intent: ");
13311                            intents.get(i).toShortString(sb, false, true, false, false);
13312                            pw.println(sb.toString());
13313                            Bundle bundle = intents.get(i).getExtras();
13314                            if (bundle != null) {
13315                                pw.print("      ");
13316                                pw.println(bundle.toString());
13317                            }
13318                        }
13319                    } else {
13320                        pw.println("");
13321                    }
13322                }
13323            }
13324        }
13325
13326        if (!onlyHistory && dumpAll) {
13327            pw.println();
13328            for (BroadcastQueue queue : mBroadcastQueues) {
13329                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13330                        + queue.mBroadcastsScheduled);
13331            }
13332            pw.println("  mHandler:");
13333            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13334            needSep = true;
13335            printedAnything = true;
13336        }
13337
13338        if (!printedAnything) {
13339            pw.println("  (nothing)");
13340        }
13341    }
13342
13343    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13344            int opti, boolean dumpAll, String dumpPackage) {
13345        boolean needSep;
13346        boolean printedAnything = false;
13347
13348        ItemMatcher matcher = new ItemMatcher();
13349        matcher.build(args, opti);
13350
13351        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13352
13353        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13354        printedAnything |= needSep;
13355
13356        if (mLaunchingProviders.size() > 0) {
13357            boolean printed = false;
13358            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13359                ContentProviderRecord r = mLaunchingProviders.get(i);
13360                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13361                    continue;
13362                }
13363                if (!printed) {
13364                    if (needSep) pw.println();
13365                    needSep = true;
13366                    pw.println("  Launching content providers:");
13367                    printed = true;
13368                    printedAnything = true;
13369                }
13370                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13371                        pw.println(r);
13372            }
13373        }
13374
13375        if (mGrantedUriPermissions.size() > 0) {
13376            boolean printed = false;
13377            int dumpUid = -2;
13378            if (dumpPackage != null) {
13379                try {
13380                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13381                } catch (NameNotFoundException e) {
13382                    dumpUid = -1;
13383                }
13384            }
13385            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13386                int uid = mGrantedUriPermissions.keyAt(i);
13387                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13388                    continue;
13389                }
13390                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13391                if (!printed) {
13392                    if (needSep) pw.println();
13393                    needSep = true;
13394                    pw.println("  Granted Uri Permissions:");
13395                    printed = true;
13396                    printedAnything = true;
13397                }
13398                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13399                for (UriPermission perm : perms.values()) {
13400                    pw.print("    "); pw.println(perm);
13401                    if (dumpAll) {
13402                        perm.dump(pw, "      ");
13403                    }
13404                }
13405            }
13406        }
13407
13408        if (!printedAnything) {
13409            pw.println("  (nothing)");
13410        }
13411    }
13412
13413    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13414            int opti, boolean dumpAll, String dumpPackage) {
13415        boolean printed = false;
13416
13417        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13418
13419        if (mIntentSenderRecords.size() > 0) {
13420            Iterator<WeakReference<PendingIntentRecord>> it
13421                    = mIntentSenderRecords.values().iterator();
13422            while (it.hasNext()) {
13423                WeakReference<PendingIntentRecord> ref = it.next();
13424                PendingIntentRecord rec = ref != null ? ref.get(): null;
13425                if (dumpPackage != null && (rec == null
13426                        || !dumpPackage.equals(rec.key.packageName))) {
13427                    continue;
13428                }
13429                printed = true;
13430                if (rec != null) {
13431                    pw.print("  * "); pw.println(rec);
13432                    if (dumpAll) {
13433                        rec.dump(pw, "    ");
13434                    }
13435                } else {
13436                    pw.print("  * "); pw.println(ref);
13437                }
13438            }
13439        }
13440
13441        if (!printed) {
13442            pw.println("  (nothing)");
13443        }
13444    }
13445
13446    private static final int dumpProcessList(PrintWriter pw,
13447            ActivityManagerService service, List list,
13448            String prefix, String normalLabel, String persistentLabel,
13449            String dumpPackage) {
13450        int numPers = 0;
13451        final int N = list.size()-1;
13452        for (int i=N; i>=0; i--) {
13453            ProcessRecord r = (ProcessRecord)list.get(i);
13454            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13455                continue;
13456            }
13457            pw.println(String.format("%s%s #%2d: %s",
13458                    prefix, (r.persistent ? persistentLabel : normalLabel),
13459                    i, r.toString()));
13460            if (r.persistent) {
13461                numPers++;
13462            }
13463        }
13464        return numPers;
13465    }
13466
13467    private static final boolean dumpProcessOomList(PrintWriter pw,
13468            ActivityManagerService service, List<ProcessRecord> origList,
13469            String prefix, String normalLabel, String persistentLabel,
13470            boolean inclDetails, String dumpPackage) {
13471
13472        ArrayList<Pair<ProcessRecord, Integer>> list
13473                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13474        for (int i=0; i<origList.size(); i++) {
13475            ProcessRecord r = origList.get(i);
13476            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13477                continue;
13478            }
13479            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13480        }
13481
13482        if (list.size() <= 0) {
13483            return false;
13484        }
13485
13486        Comparator<Pair<ProcessRecord, Integer>> comparator
13487                = new Comparator<Pair<ProcessRecord, Integer>>() {
13488            @Override
13489            public int compare(Pair<ProcessRecord, Integer> object1,
13490                    Pair<ProcessRecord, Integer> object2) {
13491                if (object1.first.setAdj != object2.first.setAdj) {
13492                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13493                }
13494                if (object1.second.intValue() != object2.second.intValue()) {
13495                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13496                }
13497                return 0;
13498            }
13499        };
13500
13501        Collections.sort(list, comparator);
13502
13503        final long curRealtime = SystemClock.elapsedRealtime();
13504        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13505        final long curUptime = SystemClock.uptimeMillis();
13506        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13507
13508        for (int i=list.size()-1; i>=0; i--) {
13509            ProcessRecord r = list.get(i).first;
13510            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13511            char schedGroup;
13512            switch (r.setSchedGroup) {
13513                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13514                    schedGroup = 'B';
13515                    break;
13516                case Process.THREAD_GROUP_DEFAULT:
13517                    schedGroup = 'F';
13518                    break;
13519                default:
13520                    schedGroup = '?';
13521                    break;
13522            }
13523            char foreground;
13524            if (r.foregroundActivities) {
13525                foreground = 'A';
13526            } else if (r.foregroundServices) {
13527                foreground = 'S';
13528            } else {
13529                foreground = ' ';
13530            }
13531            String procState = ProcessList.makeProcStateString(r.curProcState);
13532            pw.print(prefix);
13533            pw.print(r.persistent ? persistentLabel : normalLabel);
13534            pw.print(" #");
13535            int num = (origList.size()-1)-list.get(i).second;
13536            if (num < 10) pw.print(' ');
13537            pw.print(num);
13538            pw.print(": ");
13539            pw.print(oomAdj);
13540            pw.print(' ');
13541            pw.print(schedGroup);
13542            pw.print('/');
13543            pw.print(foreground);
13544            pw.print('/');
13545            pw.print(procState);
13546            pw.print(" trm:");
13547            if (r.trimMemoryLevel < 10) pw.print(' ');
13548            pw.print(r.trimMemoryLevel);
13549            pw.print(' ');
13550            pw.print(r.toShortString());
13551            pw.print(" (");
13552            pw.print(r.adjType);
13553            pw.println(')');
13554            if (r.adjSource != null || r.adjTarget != null) {
13555                pw.print(prefix);
13556                pw.print("    ");
13557                if (r.adjTarget instanceof ComponentName) {
13558                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13559                } else if (r.adjTarget != null) {
13560                    pw.print(r.adjTarget.toString());
13561                } else {
13562                    pw.print("{null}");
13563                }
13564                pw.print("<=");
13565                if (r.adjSource instanceof ProcessRecord) {
13566                    pw.print("Proc{");
13567                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13568                    pw.println("}");
13569                } else if (r.adjSource != null) {
13570                    pw.println(r.adjSource.toString());
13571                } else {
13572                    pw.println("{null}");
13573                }
13574            }
13575            if (inclDetails) {
13576                pw.print(prefix);
13577                pw.print("    ");
13578                pw.print("oom: max="); pw.print(r.maxAdj);
13579                pw.print(" curRaw="); pw.print(r.curRawAdj);
13580                pw.print(" setRaw="); pw.print(r.setRawAdj);
13581                pw.print(" cur="); pw.print(r.curAdj);
13582                pw.print(" set="); pw.println(r.setAdj);
13583                pw.print(prefix);
13584                pw.print("    ");
13585                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13586                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13587                pw.print(" lastPss="); pw.print(r.lastPss);
13588                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13589                pw.print(prefix);
13590                pw.print("    ");
13591                pw.print("cached="); pw.print(r.cached);
13592                pw.print(" empty="); pw.print(r.empty);
13593                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13594
13595                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13596                    if (r.lastWakeTime != 0) {
13597                        long wtime;
13598                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13599                        synchronized (stats) {
13600                            wtime = stats.getProcessWakeTime(r.info.uid,
13601                                    r.pid, curRealtime);
13602                        }
13603                        long timeUsed = wtime - r.lastWakeTime;
13604                        pw.print(prefix);
13605                        pw.print("    ");
13606                        pw.print("keep awake over ");
13607                        TimeUtils.formatDuration(realtimeSince, pw);
13608                        pw.print(" used ");
13609                        TimeUtils.formatDuration(timeUsed, pw);
13610                        pw.print(" (");
13611                        pw.print((timeUsed*100)/realtimeSince);
13612                        pw.println("%)");
13613                    }
13614                    if (r.lastCpuTime != 0) {
13615                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13616                        pw.print(prefix);
13617                        pw.print("    ");
13618                        pw.print("run cpu over ");
13619                        TimeUtils.formatDuration(uptimeSince, pw);
13620                        pw.print(" used ");
13621                        TimeUtils.formatDuration(timeUsed, pw);
13622                        pw.print(" (");
13623                        pw.print((timeUsed*100)/uptimeSince);
13624                        pw.println("%)");
13625                    }
13626                }
13627            }
13628        }
13629        return true;
13630    }
13631
13632    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13633            String[] args) {
13634        ArrayList<ProcessRecord> procs;
13635        synchronized (this) {
13636            if (args != null && args.length > start
13637                    && args[start].charAt(0) != '-') {
13638                procs = new ArrayList<ProcessRecord>();
13639                int pid = -1;
13640                try {
13641                    pid = Integer.parseInt(args[start]);
13642                } catch (NumberFormatException e) {
13643                }
13644                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13645                    ProcessRecord proc = mLruProcesses.get(i);
13646                    if (proc.pid == pid) {
13647                        procs.add(proc);
13648                    } else if (allPkgs && proc.pkgList != null
13649                            && proc.pkgList.containsKey(args[start])) {
13650                        procs.add(proc);
13651                    } else if (proc.processName.equals(args[start])) {
13652                        procs.add(proc);
13653                    }
13654                }
13655                if (procs.size() <= 0) {
13656                    return null;
13657                }
13658            } else {
13659                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13660            }
13661        }
13662        return procs;
13663    }
13664
13665    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13666            PrintWriter pw, String[] args) {
13667        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13668        if (procs == null) {
13669            pw.println("No process found for: " + args[0]);
13670            return;
13671        }
13672
13673        long uptime = SystemClock.uptimeMillis();
13674        long realtime = SystemClock.elapsedRealtime();
13675        pw.println("Applications Graphics Acceleration Info:");
13676        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13677
13678        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13679            ProcessRecord r = procs.get(i);
13680            if (r.thread != null) {
13681                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13682                pw.flush();
13683                try {
13684                    TransferPipe tp = new TransferPipe();
13685                    try {
13686                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13687                        tp.go(fd);
13688                    } finally {
13689                        tp.kill();
13690                    }
13691                } catch (IOException e) {
13692                    pw.println("Failure while dumping the app: " + r);
13693                    pw.flush();
13694                } catch (RemoteException e) {
13695                    pw.println("Got a RemoteException while dumping the app " + r);
13696                    pw.flush();
13697                }
13698            }
13699        }
13700    }
13701
13702    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13703        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13704        if (procs == null) {
13705            pw.println("No process found for: " + args[0]);
13706            return;
13707        }
13708
13709        pw.println("Applications Database Info:");
13710
13711        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13712            ProcessRecord r = procs.get(i);
13713            if (r.thread != null) {
13714                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13715                pw.flush();
13716                try {
13717                    TransferPipe tp = new TransferPipe();
13718                    try {
13719                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13720                        tp.go(fd);
13721                    } finally {
13722                        tp.kill();
13723                    }
13724                } catch (IOException e) {
13725                    pw.println("Failure while dumping the app: " + r);
13726                    pw.flush();
13727                } catch (RemoteException e) {
13728                    pw.println("Got a RemoteException while dumping the app " + r);
13729                    pw.flush();
13730                }
13731            }
13732        }
13733    }
13734
13735    final static class MemItem {
13736        final boolean isProc;
13737        final String label;
13738        final String shortLabel;
13739        final long pss;
13740        final int id;
13741        final boolean hasActivities;
13742        ArrayList<MemItem> subitems;
13743
13744        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13745                boolean _hasActivities) {
13746            isProc = true;
13747            label = _label;
13748            shortLabel = _shortLabel;
13749            pss = _pss;
13750            id = _id;
13751            hasActivities = _hasActivities;
13752        }
13753
13754        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13755            isProc = false;
13756            label = _label;
13757            shortLabel = _shortLabel;
13758            pss = _pss;
13759            id = _id;
13760            hasActivities = false;
13761        }
13762    }
13763
13764    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13765            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13766        if (sort && !isCompact) {
13767            Collections.sort(items, new Comparator<MemItem>() {
13768                @Override
13769                public int compare(MemItem lhs, MemItem rhs) {
13770                    if (lhs.pss < rhs.pss) {
13771                        return 1;
13772                    } else if (lhs.pss > rhs.pss) {
13773                        return -1;
13774                    }
13775                    return 0;
13776                }
13777            });
13778        }
13779
13780        for (int i=0; i<items.size(); i++) {
13781            MemItem mi = items.get(i);
13782            if (!isCompact) {
13783                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13784            } else if (mi.isProc) {
13785                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13786                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13787                pw.println(mi.hasActivities ? ",a" : ",e");
13788            } else {
13789                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13790                pw.println(mi.pss);
13791            }
13792            if (mi.subitems != null) {
13793                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13794                        true, isCompact);
13795            }
13796        }
13797    }
13798
13799    // These are in KB.
13800    static final long[] DUMP_MEM_BUCKETS = new long[] {
13801        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13802        120*1024, 160*1024, 200*1024,
13803        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13804        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13805    };
13806
13807    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13808            boolean stackLike) {
13809        int start = label.lastIndexOf('.');
13810        if (start >= 0) start++;
13811        else start = 0;
13812        int end = label.length();
13813        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13814            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13815                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13816                out.append(bucket);
13817                out.append(stackLike ? "MB." : "MB ");
13818                out.append(label, start, end);
13819                return;
13820            }
13821        }
13822        out.append(memKB/1024);
13823        out.append(stackLike ? "MB." : "MB ");
13824        out.append(label, start, end);
13825    }
13826
13827    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13828            ProcessList.NATIVE_ADJ,
13829            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13830            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13831            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13832            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13833            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13834            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13835    };
13836    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13837            "Native",
13838            "System", "Persistent", "Persistent Service", "Foreground",
13839            "Visible", "Perceptible",
13840            "Heavy Weight", "Backup",
13841            "A Services", "Home",
13842            "Previous", "B Services", "Cached"
13843    };
13844    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13845            "native",
13846            "sys", "pers", "persvc", "fore",
13847            "vis", "percept",
13848            "heavy", "backup",
13849            "servicea", "home",
13850            "prev", "serviceb", "cached"
13851    };
13852
13853    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13854            long realtime, boolean isCheckinRequest, boolean isCompact) {
13855        if (isCheckinRequest || isCompact) {
13856            // short checkin version
13857            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13858        } else {
13859            pw.println("Applications Memory Usage (kB):");
13860            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13861        }
13862    }
13863
13864    private static final int KSM_SHARED = 0;
13865    private static final int KSM_SHARING = 1;
13866    private static final int KSM_UNSHARED = 2;
13867    private static final int KSM_VOLATILE = 3;
13868
13869    private final long[] getKsmInfo() {
13870        long[] longOut = new long[4];
13871        final int[] SINGLE_LONG_FORMAT = new int[] {
13872            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13873        };
13874        long[] longTmp = new long[1];
13875        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13876                SINGLE_LONG_FORMAT, null, longTmp, null);
13877        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13878        longTmp[0] = 0;
13879        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13880                SINGLE_LONG_FORMAT, null, longTmp, null);
13881        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13882        longTmp[0] = 0;
13883        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13884                SINGLE_LONG_FORMAT, null, longTmp, null);
13885        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13886        longTmp[0] = 0;
13887        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13888                SINGLE_LONG_FORMAT, null, longTmp, null);
13889        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13890        return longOut;
13891    }
13892
13893    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13894            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13895        boolean dumpDetails = false;
13896        boolean dumpFullDetails = false;
13897        boolean dumpDalvik = false;
13898        boolean oomOnly = false;
13899        boolean isCompact = false;
13900        boolean localOnly = false;
13901        boolean packages = false;
13902
13903        int opti = 0;
13904        while (opti < args.length) {
13905            String opt = args[opti];
13906            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13907                break;
13908            }
13909            opti++;
13910            if ("-a".equals(opt)) {
13911                dumpDetails = true;
13912                dumpFullDetails = true;
13913                dumpDalvik = true;
13914            } else if ("-d".equals(opt)) {
13915                dumpDalvik = true;
13916            } else if ("-c".equals(opt)) {
13917                isCompact = true;
13918            } else if ("--oom".equals(opt)) {
13919                oomOnly = true;
13920            } else if ("--local".equals(opt)) {
13921                localOnly = true;
13922            } else if ("--package".equals(opt)) {
13923                packages = true;
13924            } else if ("-h".equals(opt)) {
13925                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13926                pw.println("  -a: include all available information for each process.");
13927                pw.println("  -d: include dalvik details when dumping process details.");
13928                pw.println("  -c: dump in a compact machine-parseable representation.");
13929                pw.println("  --oom: only show processes organized by oom adj.");
13930                pw.println("  --local: only collect details locally, don't call process.");
13931                pw.println("  --package: interpret process arg as package, dumping all");
13932                pw.println("             processes that have loaded that package.");
13933                pw.println("If [process] is specified it can be the name or ");
13934                pw.println("pid of a specific process to dump.");
13935                return;
13936            } else {
13937                pw.println("Unknown argument: " + opt + "; use -h for help");
13938            }
13939        }
13940
13941        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13942        long uptime = SystemClock.uptimeMillis();
13943        long realtime = SystemClock.elapsedRealtime();
13944        final long[] tmpLong = new long[1];
13945
13946        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13947        if (procs == null) {
13948            // No Java processes.  Maybe they want to print a native process.
13949            if (args != null && args.length > opti
13950                    && args[opti].charAt(0) != '-') {
13951                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13952                        = new ArrayList<ProcessCpuTracker.Stats>();
13953                updateCpuStatsNow();
13954                int findPid = -1;
13955                try {
13956                    findPid = Integer.parseInt(args[opti]);
13957                } catch (NumberFormatException e) {
13958                }
13959                synchronized (mProcessCpuTracker) {
13960                    final int N = mProcessCpuTracker.countStats();
13961                    for (int i=0; i<N; i++) {
13962                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13963                        if (st.pid == findPid || (st.baseName != null
13964                                && st.baseName.equals(args[opti]))) {
13965                            nativeProcs.add(st);
13966                        }
13967                    }
13968                }
13969                if (nativeProcs.size() > 0) {
13970                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13971                            isCompact);
13972                    Debug.MemoryInfo mi = null;
13973                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13974                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13975                        final int pid = r.pid;
13976                        if (!isCheckinRequest && dumpDetails) {
13977                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13978                        }
13979                        if (mi == null) {
13980                            mi = new Debug.MemoryInfo();
13981                        }
13982                        if (dumpDetails || (!brief && !oomOnly)) {
13983                            Debug.getMemoryInfo(pid, mi);
13984                        } else {
13985                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13986                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13987                        }
13988                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13989                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13990                        if (isCheckinRequest) {
13991                            pw.println();
13992                        }
13993                    }
13994                    return;
13995                }
13996            }
13997            pw.println("No process found for: " + args[opti]);
13998            return;
13999        }
14000
14001        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14002            dumpDetails = true;
14003        }
14004
14005        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14006
14007        String[] innerArgs = new String[args.length-opti];
14008        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14009
14010        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14011        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14012        long nativePss = 0;
14013        long dalvikPss = 0;
14014        long otherPss = 0;
14015        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14016
14017        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14018        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14019                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14020
14021        long totalPss = 0;
14022        long cachedPss = 0;
14023
14024        Debug.MemoryInfo mi = null;
14025        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14026            final ProcessRecord r = procs.get(i);
14027            final IApplicationThread thread;
14028            final int pid;
14029            final int oomAdj;
14030            final boolean hasActivities;
14031            synchronized (this) {
14032                thread = r.thread;
14033                pid = r.pid;
14034                oomAdj = r.getSetAdjWithServices();
14035                hasActivities = r.activities.size() > 0;
14036            }
14037            if (thread != null) {
14038                if (!isCheckinRequest && dumpDetails) {
14039                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14040                }
14041                if (mi == null) {
14042                    mi = new Debug.MemoryInfo();
14043                }
14044                if (dumpDetails || (!brief && !oomOnly)) {
14045                    Debug.getMemoryInfo(pid, mi);
14046                } else {
14047                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14048                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14049                }
14050                if (dumpDetails) {
14051                    if (localOnly) {
14052                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14053                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14054                        if (isCheckinRequest) {
14055                            pw.println();
14056                        }
14057                    } else {
14058                        try {
14059                            pw.flush();
14060                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14061                                    dumpDalvik, innerArgs);
14062                        } catch (RemoteException e) {
14063                            if (!isCheckinRequest) {
14064                                pw.println("Got RemoteException!");
14065                                pw.flush();
14066                            }
14067                        }
14068                    }
14069                }
14070
14071                final long myTotalPss = mi.getTotalPss();
14072                final long myTotalUss = mi.getTotalUss();
14073
14074                synchronized (this) {
14075                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14076                        // Record this for posterity if the process has been stable.
14077                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14078                    }
14079                }
14080
14081                if (!isCheckinRequest && mi != null) {
14082                    totalPss += myTotalPss;
14083                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14084                            (hasActivities ? " / activities)" : ")"),
14085                            r.processName, myTotalPss, pid, hasActivities);
14086                    procMems.add(pssItem);
14087                    procMemsMap.put(pid, pssItem);
14088
14089                    nativePss += mi.nativePss;
14090                    dalvikPss += mi.dalvikPss;
14091                    otherPss += mi.otherPss;
14092                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14093                        long mem = mi.getOtherPss(j);
14094                        miscPss[j] += mem;
14095                        otherPss -= mem;
14096                    }
14097
14098                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14099                        cachedPss += myTotalPss;
14100                    }
14101
14102                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14103                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14104                                || oomIndex == (oomPss.length-1)) {
14105                            oomPss[oomIndex] += myTotalPss;
14106                            if (oomProcs[oomIndex] == null) {
14107                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14108                            }
14109                            oomProcs[oomIndex].add(pssItem);
14110                            break;
14111                        }
14112                    }
14113                }
14114            }
14115        }
14116
14117        long nativeProcTotalPss = 0;
14118
14119        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14120            // If we are showing aggregations, also look for native processes to
14121            // include so that our aggregations are more accurate.
14122            updateCpuStatsNow();
14123            synchronized (mProcessCpuTracker) {
14124                final int N = mProcessCpuTracker.countStats();
14125                for (int i=0; i<N; i++) {
14126                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14127                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14128                        if (mi == null) {
14129                            mi = new Debug.MemoryInfo();
14130                        }
14131                        if (!brief && !oomOnly) {
14132                            Debug.getMemoryInfo(st.pid, mi);
14133                        } else {
14134                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14135                            mi.nativePrivateDirty = (int)tmpLong[0];
14136                        }
14137
14138                        final long myTotalPss = mi.getTotalPss();
14139                        totalPss += myTotalPss;
14140                        nativeProcTotalPss += myTotalPss;
14141
14142                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14143                                st.name, myTotalPss, st.pid, false);
14144                        procMems.add(pssItem);
14145
14146                        nativePss += mi.nativePss;
14147                        dalvikPss += mi.dalvikPss;
14148                        otherPss += mi.otherPss;
14149                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14150                            long mem = mi.getOtherPss(j);
14151                            miscPss[j] += mem;
14152                            otherPss -= mem;
14153                        }
14154                        oomPss[0] += myTotalPss;
14155                        if (oomProcs[0] == null) {
14156                            oomProcs[0] = new ArrayList<MemItem>();
14157                        }
14158                        oomProcs[0].add(pssItem);
14159                    }
14160                }
14161            }
14162
14163            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14164
14165            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14166            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14167            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14168            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14169                String label = Debug.MemoryInfo.getOtherLabel(j);
14170                catMems.add(new MemItem(label, label, miscPss[j], j));
14171            }
14172
14173            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14174            for (int j=0; j<oomPss.length; j++) {
14175                if (oomPss[j] != 0) {
14176                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14177                            : DUMP_MEM_OOM_LABEL[j];
14178                    MemItem item = new MemItem(label, label, oomPss[j],
14179                            DUMP_MEM_OOM_ADJ[j]);
14180                    item.subitems = oomProcs[j];
14181                    oomMems.add(item);
14182                }
14183            }
14184
14185            if (!brief && !oomOnly && !isCompact) {
14186                pw.println();
14187                pw.println("Total PSS by process:");
14188                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14189                pw.println();
14190            }
14191            if (!isCompact) {
14192                pw.println("Total PSS by OOM adjustment:");
14193            }
14194            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14195            if (!brief && !oomOnly) {
14196                PrintWriter out = categoryPw != null ? categoryPw : pw;
14197                if (!isCompact) {
14198                    out.println();
14199                    out.println("Total PSS by category:");
14200                }
14201                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14202            }
14203            if (!isCompact) {
14204                pw.println();
14205            }
14206            MemInfoReader memInfo = new MemInfoReader();
14207            memInfo.readMemInfo();
14208            if (nativeProcTotalPss > 0) {
14209                synchronized (this) {
14210                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14211                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14212                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14213                }
14214            }
14215            if (!brief) {
14216                if (!isCompact) {
14217                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14218                    pw.print(" kB (status ");
14219                    switch (mLastMemoryLevel) {
14220                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14221                            pw.println("normal)");
14222                            break;
14223                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14224                            pw.println("moderate)");
14225                            break;
14226                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14227                            pw.println("low)");
14228                            break;
14229                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14230                            pw.println("critical)");
14231                            break;
14232                        default:
14233                            pw.print(mLastMemoryLevel);
14234                            pw.println(")");
14235                            break;
14236                    }
14237                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14238                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14239                            pw.print(cachedPss); pw.print(" cached pss + ");
14240                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14241                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14242                } else {
14243                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14244                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14245                            + memInfo.getFreeSizeKb()); pw.print(",");
14246                    pw.println(totalPss - cachedPss);
14247                }
14248            }
14249            if (!isCompact) {
14250                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14251                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14252                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14253                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14254                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14255                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14256                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14257            }
14258            if (!brief) {
14259                if (memInfo.getZramTotalSizeKb() != 0) {
14260                    if (!isCompact) {
14261                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14262                                pw.print(" kB physical used for ");
14263                                pw.print(memInfo.getSwapTotalSizeKb()
14264                                        - memInfo.getSwapFreeSizeKb());
14265                                pw.print(" kB in swap (");
14266                                pw.print(memInfo.getSwapTotalSizeKb());
14267                                pw.println(" kB total swap)");
14268                    } else {
14269                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14270                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14271                                pw.println(memInfo.getSwapFreeSizeKb());
14272                    }
14273                }
14274                final long[] ksm = getKsmInfo();
14275                if (!isCompact) {
14276                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14277                            || ksm[KSM_VOLATILE] != 0) {
14278                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14279                                pw.print(" kB saved from shared ");
14280                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14281                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14282                                pw.print(" kB unshared; ");
14283                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14284                    }
14285                    pw.print("   Tuning: ");
14286                    pw.print(ActivityManager.staticGetMemoryClass());
14287                    pw.print(" (large ");
14288                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14289                    pw.print("), oom ");
14290                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14291                    pw.print(" kB");
14292                    pw.print(", restore limit ");
14293                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14294                    pw.print(" kB");
14295                    if (ActivityManager.isLowRamDeviceStatic()) {
14296                        pw.print(" (low-ram)");
14297                    }
14298                    if (ActivityManager.isHighEndGfx()) {
14299                        pw.print(" (high-end-gfx)");
14300                    }
14301                    pw.println();
14302                } else {
14303                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14304                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14305                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14306                    pw.print("tuning,");
14307                    pw.print(ActivityManager.staticGetMemoryClass());
14308                    pw.print(',');
14309                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14310                    pw.print(',');
14311                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14312                    if (ActivityManager.isLowRamDeviceStatic()) {
14313                        pw.print(",low-ram");
14314                    }
14315                    if (ActivityManager.isHighEndGfx()) {
14316                        pw.print(",high-end-gfx");
14317                    }
14318                    pw.println();
14319                }
14320            }
14321        }
14322    }
14323
14324    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14325            String name) {
14326        sb.append("  ");
14327        sb.append(ProcessList.makeOomAdjString(oomAdj));
14328        sb.append(' ');
14329        sb.append(ProcessList.makeProcStateString(procState));
14330        sb.append(' ');
14331        ProcessList.appendRamKb(sb, pss);
14332        sb.append(" kB: ");
14333        sb.append(name);
14334    }
14335
14336    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14337        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14338        sb.append(" (");
14339        sb.append(mi.pid);
14340        sb.append(") ");
14341        sb.append(mi.adjType);
14342        sb.append('\n');
14343        if (mi.adjReason != null) {
14344            sb.append("                      ");
14345            sb.append(mi.adjReason);
14346            sb.append('\n');
14347        }
14348    }
14349
14350    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14351        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14352        for (int i=0, N=memInfos.size(); i<N; i++) {
14353            ProcessMemInfo mi = memInfos.get(i);
14354            infoMap.put(mi.pid, mi);
14355        }
14356        updateCpuStatsNow();
14357        synchronized (mProcessCpuTracker) {
14358            final int N = mProcessCpuTracker.countStats();
14359            for (int i=0; i<N; i++) {
14360                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14361                if (st.vsize > 0) {
14362                    long pss = Debug.getPss(st.pid, null);
14363                    if (pss > 0) {
14364                        if (infoMap.indexOfKey(st.pid) < 0) {
14365                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14366                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14367                            mi.pss = pss;
14368                            memInfos.add(mi);
14369                        }
14370                    }
14371                }
14372            }
14373        }
14374
14375        long totalPss = 0;
14376        for (int i=0, N=memInfos.size(); i<N; i++) {
14377            ProcessMemInfo mi = memInfos.get(i);
14378            if (mi.pss == 0) {
14379                mi.pss = Debug.getPss(mi.pid, null);
14380            }
14381            totalPss += mi.pss;
14382        }
14383        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14384            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14385                if (lhs.oomAdj != rhs.oomAdj) {
14386                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14387                }
14388                if (lhs.pss != rhs.pss) {
14389                    return lhs.pss < rhs.pss ? 1 : -1;
14390                }
14391                return 0;
14392            }
14393        });
14394
14395        StringBuilder tag = new StringBuilder(128);
14396        StringBuilder stack = new StringBuilder(128);
14397        tag.append("Low on memory -- ");
14398        appendMemBucket(tag, totalPss, "total", false);
14399        appendMemBucket(stack, totalPss, "total", true);
14400
14401        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14402        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14403        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14404
14405        boolean firstLine = true;
14406        int lastOomAdj = Integer.MIN_VALUE;
14407        long extraNativeRam = 0;
14408        long cachedPss = 0;
14409        for (int i=0, N=memInfos.size(); i<N; i++) {
14410            ProcessMemInfo mi = memInfos.get(i);
14411
14412            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14413                cachedPss += mi.pss;
14414            }
14415
14416            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14417                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14418                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14419                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14420                if (lastOomAdj != mi.oomAdj) {
14421                    lastOomAdj = mi.oomAdj;
14422                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14423                        tag.append(" / ");
14424                    }
14425                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14426                        if (firstLine) {
14427                            stack.append(":");
14428                            firstLine = false;
14429                        }
14430                        stack.append("\n\t at ");
14431                    } else {
14432                        stack.append("$");
14433                    }
14434                } else {
14435                    tag.append(" ");
14436                    stack.append("$");
14437                }
14438                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14439                    appendMemBucket(tag, mi.pss, mi.name, false);
14440                }
14441                appendMemBucket(stack, mi.pss, mi.name, true);
14442                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14443                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14444                    stack.append("(");
14445                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14446                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14447                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14448                            stack.append(":");
14449                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14450                        }
14451                    }
14452                    stack.append(")");
14453                }
14454            }
14455
14456            appendMemInfo(fullNativeBuilder, mi);
14457            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14458                // The short form only has native processes that are >= 1MB.
14459                if (mi.pss >= 1000) {
14460                    appendMemInfo(shortNativeBuilder, mi);
14461                } else {
14462                    extraNativeRam += mi.pss;
14463                }
14464            } else {
14465                // Short form has all other details, but if we have collected RAM
14466                // from smaller native processes let's dump a summary of that.
14467                if (extraNativeRam > 0) {
14468                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14469                            -1, extraNativeRam, "(Other native)");
14470                    shortNativeBuilder.append('\n');
14471                    extraNativeRam = 0;
14472                }
14473                appendMemInfo(fullJavaBuilder, mi);
14474            }
14475        }
14476
14477        fullJavaBuilder.append("           ");
14478        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14479        fullJavaBuilder.append(" kB: TOTAL\n");
14480
14481        MemInfoReader memInfo = new MemInfoReader();
14482        memInfo.readMemInfo();
14483        final long[] infos = memInfo.getRawInfo();
14484
14485        StringBuilder memInfoBuilder = new StringBuilder(1024);
14486        Debug.getMemInfo(infos);
14487        memInfoBuilder.append("  MemInfo: ");
14488        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14489        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14490        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14491        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14492        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14493        memInfoBuilder.append("           ");
14494        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14495        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14496        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14497        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14498        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14499            memInfoBuilder.append("  ZRAM: ");
14500            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14501            memInfoBuilder.append(" kB RAM, ");
14502            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14503            memInfoBuilder.append(" kB swap total, ");
14504            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14505            memInfoBuilder.append(" kB swap free\n");
14506        }
14507        final long[] ksm = getKsmInfo();
14508        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14509                || ksm[KSM_VOLATILE] != 0) {
14510            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14511            memInfoBuilder.append(" kB saved from shared ");
14512            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14513            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14514            memInfoBuilder.append(" kB unshared; ");
14515            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14516        }
14517        memInfoBuilder.append("  Free RAM: ");
14518        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14519                + memInfo.getFreeSizeKb());
14520        memInfoBuilder.append(" kB\n");
14521        memInfoBuilder.append("  Used RAM: ");
14522        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14523        memInfoBuilder.append(" kB\n");
14524        memInfoBuilder.append("  Lost RAM: ");
14525        memInfoBuilder.append(memInfo.getTotalSizeKb()
14526                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14527                - memInfo.getKernelUsedSizeKb());
14528        memInfoBuilder.append(" kB\n");
14529        Slog.i(TAG, "Low on memory:");
14530        Slog.i(TAG, shortNativeBuilder.toString());
14531        Slog.i(TAG, fullJavaBuilder.toString());
14532        Slog.i(TAG, memInfoBuilder.toString());
14533
14534        StringBuilder dropBuilder = new StringBuilder(1024);
14535        /*
14536        StringWriter oomSw = new StringWriter();
14537        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14538        StringWriter catSw = new StringWriter();
14539        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14540        String[] emptyArgs = new String[] { };
14541        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14542        oomPw.flush();
14543        String oomString = oomSw.toString();
14544        */
14545        dropBuilder.append("Low on memory:");
14546        dropBuilder.append(stack);
14547        dropBuilder.append('\n');
14548        dropBuilder.append(fullNativeBuilder);
14549        dropBuilder.append(fullJavaBuilder);
14550        dropBuilder.append('\n');
14551        dropBuilder.append(memInfoBuilder);
14552        dropBuilder.append('\n');
14553        /*
14554        dropBuilder.append(oomString);
14555        dropBuilder.append('\n');
14556        */
14557        StringWriter catSw = new StringWriter();
14558        synchronized (ActivityManagerService.this) {
14559            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14560            String[] emptyArgs = new String[] { };
14561            catPw.println();
14562            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14563            catPw.println();
14564            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14565                    false, false, null);
14566            catPw.println();
14567            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14568            catPw.flush();
14569        }
14570        dropBuilder.append(catSw.toString());
14571        addErrorToDropBox("lowmem", null, "system_server", null,
14572                null, tag.toString(), dropBuilder.toString(), null, null);
14573        //Slog.i(TAG, "Sent to dropbox:");
14574        //Slog.i(TAG, dropBuilder.toString());
14575        synchronized (ActivityManagerService.this) {
14576            long now = SystemClock.uptimeMillis();
14577            if (mLastMemUsageReportTime < now) {
14578                mLastMemUsageReportTime = now;
14579            }
14580        }
14581    }
14582
14583    /**
14584     * Searches array of arguments for the specified string
14585     * @param args array of argument strings
14586     * @param value value to search for
14587     * @return true if the value is contained in the array
14588     */
14589    private static boolean scanArgs(String[] args, String value) {
14590        if (args != null) {
14591            for (String arg : args) {
14592                if (value.equals(arg)) {
14593                    return true;
14594                }
14595            }
14596        }
14597        return false;
14598    }
14599
14600    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14601            ContentProviderRecord cpr, boolean always) {
14602        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14603
14604        if (!inLaunching || always) {
14605            synchronized (cpr) {
14606                cpr.launchingApp = null;
14607                cpr.notifyAll();
14608            }
14609            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14610            String names[] = cpr.info.authority.split(";");
14611            for (int j = 0; j < names.length; j++) {
14612                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14613            }
14614        }
14615
14616        for (int i=0; i<cpr.connections.size(); i++) {
14617            ContentProviderConnection conn = cpr.connections.get(i);
14618            if (conn.waiting) {
14619                // If this connection is waiting for the provider, then we don't
14620                // need to mess with its process unless we are always removing
14621                // or for some reason the provider is not currently launching.
14622                if (inLaunching && !always) {
14623                    continue;
14624                }
14625            }
14626            ProcessRecord capp = conn.client;
14627            conn.dead = true;
14628            if (conn.stableCount > 0) {
14629                if (!capp.persistent && capp.thread != null
14630                        && capp.pid != 0
14631                        && capp.pid != MY_PID) {
14632                    capp.kill("depends on provider "
14633                            + cpr.name.flattenToShortString()
14634                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14635                }
14636            } else if (capp.thread != null && conn.provider.provider != null) {
14637                try {
14638                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14639                } catch (RemoteException e) {
14640                }
14641                // In the protocol here, we don't expect the client to correctly
14642                // clean up this connection, we'll just remove it.
14643                cpr.connections.remove(i);
14644                conn.client.conProviders.remove(conn);
14645            }
14646        }
14647
14648        if (inLaunching && always) {
14649            mLaunchingProviders.remove(cpr);
14650        }
14651        return inLaunching;
14652    }
14653
14654    /**
14655     * Main code for cleaning up a process when it has gone away.  This is
14656     * called both as a result of the process dying, or directly when stopping
14657     * a process when running in single process mode.
14658     *
14659     * @return Returns true if the given process has been restarted, so the
14660     * app that was passed in must remain on the process lists.
14661     */
14662    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14663            boolean restarting, boolean allowRestart, int index) {
14664        if (index >= 0) {
14665            removeLruProcessLocked(app);
14666            ProcessList.remove(app.pid);
14667        }
14668
14669        mProcessesToGc.remove(app);
14670        mPendingPssProcesses.remove(app);
14671
14672        // Dismiss any open dialogs.
14673        if (app.crashDialog != null && !app.forceCrashReport) {
14674            app.crashDialog.dismiss();
14675            app.crashDialog = null;
14676        }
14677        if (app.anrDialog != null) {
14678            app.anrDialog.dismiss();
14679            app.anrDialog = null;
14680        }
14681        if (app.waitDialog != null) {
14682            app.waitDialog.dismiss();
14683            app.waitDialog = null;
14684        }
14685
14686        app.crashing = false;
14687        app.notResponding = false;
14688
14689        app.resetPackageList(mProcessStats);
14690        app.unlinkDeathRecipient();
14691        app.makeInactive(mProcessStats);
14692        app.waitingToKill = null;
14693        app.forcingToForeground = null;
14694        updateProcessForegroundLocked(app, false, false);
14695        app.foregroundActivities = false;
14696        app.hasShownUi = false;
14697        app.treatLikeActivity = false;
14698        app.hasAboveClient = false;
14699        app.hasClientActivities = false;
14700
14701        mServices.killServicesLocked(app, allowRestart);
14702
14703        boolean restart = false;
14704
14705        // Remove published content providers.
14706        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14707            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14708            final boolean always = app.bad || !allowRestart;
14709            if (removeDyingProviderLocked(app, cpr, always) || always) {
14710                // We left the provider in the launching list, need to
14711                // restart it.
14712                restart = true;
14713            }
14714
14715            cpr.provider = null;
14716            cpr.proc = null;
14717        }
14718        app.pubProviders.clear();
14719
14720        // Take care of any launching providers waiting for this process.
14721        if (checkAppInLaunchingProvidersLocked(app, false)) {
14722            restart = true;
14723        }
14724
14725        // Unregister from connected content providers.
14726        if (!app.conProviders.isEmpty()) {
14727            for (int i=0; i<app.conProviders.size(); i++) {
14728                ContentProviderConnection conn = app.conProviders.get(i);
14729                conn.provider.connections.remove(conn);
14730            }
14731            app.conProviders.clear();
14732        }
14733
14734        // At this point there may be remaining entries in mLaunchingProviders
14735        // where we were the only one waiting, so they are no longer of use.
14736        // Look for these and clean up if found.
14737        // XXX Commented out for now.  Trying to figure out a way to reproduce
14738        // the actual situation to identify what is actually going on.
14739        if (false) {
14740            for (int i=0; i<mLaunchingProviders.size(); i++) {
14741                ContentProviderRecord cpr = (ContentProviderRecord)
14742                        mLaunchingProviders.get(i);
14743                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14744                    synchronized (cpr) {
14745                        cpr.launchingApp = null;
14746                        cpr.notifyAll();
14747                    }
14748                }
14749            }
14750        }
14751
14752        skipCurrentReceiverLocked(app);
14753
14754        // Unregister any receivers.
14755        for (int i=app.receivers.size()-1; i>=0; i--) {
14756            removeReceiverLocked(app.receivers.valueAt(i));
14757        }
14758        app.receivers.clear();
14759
14760        // If the app is undergoing backup, tell the backup manager about it
14761        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14762            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14763                    + mBackupTarget.appInfo + " died during backup");
14764            try {
14765                IBackupManager bm = IBackupManager.Stub.asInterface(
14766                        ServiceManager.getService(Context.BACKUP_SERVICE));
14767                bm.agentDisconnected(app.info.packageName);
14768            } catch (RemoteException e) {
14769                // can't happen; backup manager is local
14770            }
14771        }
14772
14773        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14774            ProcessChangeItem item = mPendingProcessChanges.get(i);
14775            if (item.pid == app.pid) {
14776                mPendingProcessChanges.remove(i);
14777                mAvailProcessChanges.add(item);
14778            }
14779        }
14780        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14781
14782        // If the caller is restarting this app, then leave it in its
14783        // current lists and let the caller take care of it.
14784        if (restarting) {
14785            return false;
14786        }
14787
14788        if (!app.persistent || app.isolated) {
14789            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14790                    "Removing non-persistent process during cleanup: " + app);
14791            mProcessNames.remove(app.processName, app.uid);
14792            mIsolatedProcesses.remove(app.uid);
14793            if (mHeavyWeightProcess == app) {
14794                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14795                        mHeavyWeightProcess.userId, 0));
14796                mHeavyWeightProcess = null;
14797            }
14798        } else if (!app.removed) {
14799            // This app is persistent, so we need to keep its record around.
14800            // If it is not already on the pending app list, add it there
14801            // and start a new process for it.
14802            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14803                mPersistentStartingProcesses.add(app);
14804                restart = true;
14805            }
14806        }
14807        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14808                "Clean-up removing on hold: " + app);
14809        mProcessesOnHold.remove(app);
14810
14811        if (app == mHomeProcess) {
14812            mHomeProcess = null;
14813        }
14814        if (app == mPreviousProcess) {
14815            mPreviousProcess = null;
14816        }
14817
14818        if (restart && !app.isolated) {
14819            // We have components that still need to be running in the
14820            // process, so re-launch it.
14821            if (index < 0) {
14822                ProcessList.remove(app.pid);
14823            }
14824            mProcessNames.put(app.processName, app.uid, app);
14825            startProcessLocked(app, "restart", app.processName);
14826            return true;
14827        } else if (app.pid > 0 && app.pid != MY_PID) {
14828            // Goodbye!
14829            boolean removed;
14830            synchronized (mPidsSelfLocked) {
14831                mPidsSelfLocked.remove(app.pid);
14832                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14833            }
14834            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14835            if (app.isolated) {
14836                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14837            }
14838            app.setPid(0);
14839        }
14840        return false;
14841    }
14842
14843    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14844        // Look through the content providers we are waiting to have launched,
14845        // and if any run in this process then either schedule a restart of
14846        // the process or kill the client waiting for it if this process has
14847        // gone bad.
14848        int NL = mLaunchingProviders.size();
14849        boolean restart = false;
14850        for (int i=0; i<NL; i++) {
14851            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14852            if (cpr.launchingApp == app) {
14853                if (!alwaysBad && !app.bad) {
14854                    restart = true;
14855                } else {
14856                    removeDyingProviderLocked(app, cpr, true);
14857                    // cpr should have been removed from mLaunchingProviders
14858                    NL = mLaunchingProviders.size();
14859                    i--;
14860                }
14861            }
14862        }
14863        return restart;
14864    }
14865
14866    // =========================================================
14867    // SERVICES
14868    // =========================================================
14869
14870    @Override
14871    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14872            int flags) {
14873        enforceNotIsolatedCaller("getServices");
14874        synchronized (this) {
14875            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14876        }
14877    }
14878
14879    @Override
14880    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14881        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14882        synchronized (this) {
14883            return mServices.getRunningServiceControlPanelLocked(name);
14884        }
14885    }
14886
14887    @Override
14888    public ComponentName startService(IApplicationThread caller, Intent service,
14889            String resolvedType, int userId) {
14890        enforceNotIsolatedCaller("startService");
14891        // Refuse possible leaked file descriptors
14892        if (service != null && service.hasFileDescriptors() == true) {
14893            throw new IllegalArgumentException("File descriptors passed in Intent");
14894        }
14895
14896        if (DEBUG_SERVICE)
14897            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14898        synchronized(this) {
14899            final int callingPid = Binder.getCallingPid();
14900            final int callingUid = Binder.getCallingUid();
14901            final long origId = Binder.clearCallingIdentity();
14902            ComponentName res = mServices.startServiceLocked(caller, service,
14903                    resolvedType, callingPid, callingUid, userId);
14904            Binder.restoreCallingIdentity(origId);
14905            return res;
14906        }
14907    }
14908
14909    ComponentName startServiceInPackage(int uid,
14910            Intent service, String resolvedType, int userId) {
14911        synchronized(this) {
14912            if (DEBUG_SERVICE)
14913                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14914            final long origId = Binder.clearCallingIdentity();
14915            ComponentName res = mServices.startServiceLocked(null, service,
14916                    resolvedType, -1, uid, userId);
14917            Binder.restoreCallingIdentity(origId);
14918            return res;
14919        }
14920    }
14921
14922    @Override
14923    public int stopService(IApplicationThread caller, Intent service,
14924            String resolvedType, int userId) {
14925        enforceNotIsolatedCaller("stopService");
14926        // Refuse possible leaked file descriptors
14927        if (service != null && service.hasFileDescriptors() == true) {
14928            throw new IllegalArgumentException("File descriptors passed in Intent");
14929        }
14930
14931        synchronized(this) {
14932            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14933        }
14934    }
14935
14936    @Override
14937    public IBinder peekService(Intent service, String resolvedType) {
14938        enforceNotIsolatedCaller("peekService");
14939        // Refuse possible leaked file descriptors
14940        if (service != null && service.hasFileDescriptors() == true) {
14941            throw new IllegalArgumentException("File descriptors passed in Intent");
14942        }
14943        synchronized(this) {
14944            return mServices.peekServiceLocked(service, resolvedType);
14945        }
14946    }
14947
14948    @Override
14949    public boolean stopServiceToken(ComponentName className, IBinder token,
14950            int startId) {
14951        synchronized(this) {
14952            return mServices.stopServiceTokenLocked(className, token, startId);
14953        }
14954    }
14955
14956    @Override
14957    public void setServiceForeground(ComponentName className, IBinder token,
14958            int id, Notification notification, boolean removeNotification) {
14959        synchronized(this) {
14960            mServices.setServiceForegroundLocked(className, token, id, notification,
14961                    removeNotification);
14962        }
14963    }
14964
14965    @Override
14966    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14967            boolean requireFull, String name, String callerPackage) {
14968        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14969                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14970    }
14971
14972    int unsafeConvertIncomingUser(int userId) {
14973        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14974                ? mCurrentUserId : userId;
14975    }
14976
14977    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14978            int allowMode, String name, String callerPackage) {
14979        final int callingUserId = UserHandle.getUserId(callingUid);
14980        if (callingUserId == userId) {
14981            return userId;
14982        }
14983
14984        // Note that we may be accessing mCurrentUserId outside of a lock...
14985        // shouldn't be a big deal, if this is being called outside
14986        // of a locked context there is intrinsically a race with
14987        // the value the caller will receive and someone else changing it.
14988        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14989        // we will switch to the calling user if access to the current user fails.
14990        int targetUserId = unsafeConvertIncomingUser(userId);
14991
14992        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14993            final boolean allow;
14994            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14995                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14996                // If the caller has this permission, they always pass go.  And collect $200.
14997                allow = true;
14998            } else if (allowMode == ALLOW_FULL_ONLY) {
14999                // We require full access, sucks to be you.
15000                allow = false;
15001            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15002                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15003                // If the caller does not have either permission, they are always doomed.
15004                allow = false;
15005            } else if (allowMode == ALLOW_NON_FULL) {
15006                // We are blanket allowing non-full access, you lucky caller!
15007                allow = true;
15008            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15009                // We may or may not allow this depending on whether the two users are
15010                // in the same profile.
15011                synchronized (mUserProfileGroupIdsSelfLocked) {
15012                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15013                            UserInfo.NO_PROFILE_GROUP_ID);
15014                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15015                            UserInfo.NO_PROFILE_GROUP_ID);
15016                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15017                            && callingProfile == targetProfile;
15018                }
15019            } else {
15020                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15021            }
15022            if (!allow) {
15023                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15024                    // In this case, they would like to just execute as their
15025                    // owner user instead of failing.
15026                    targetUserId = callingUserId;
15027                } else {
15028                    StringBuilder builder = new StringBuilder(128);
15029                    builder.append("Permission Denial: ");
15030                    builder.append(name);
15031                    if (callerPackage != null) {
15032                        builder.append(" from ");
15033                        builder.append(callerPackage);
15034                    }
15035                    builder.append(" asks to run as user ");
15036                    builder.append(userId);
15037                    builder.append(" but is calling from user ");
15038                    builder.append(UserHandle.getUserId(callingUid));
15039                    builder.append("; this requires ");
15040                    builder.append(INTERACT_ACROSS_USERS_FULL);
15041                    if (allowMode != ALLOW_FULL_ONLY) {
15042                        builder.append(" or ");
15043                        builder.append(INTERACT_ACROSS_USERS);
15044                    }
15045                    String msg = builder.toString();
15046                    Slog.w(TAG, msg);
15047                    throw new SecurityException(msg);
15048                }
15049            }
15050        }
15051        if (!allowAll && targetUserId < 0) {
15052            throw new IllegalArgumentException(
15053                    "Call does not support special user #" + targetUserId);
15054        }
15055        // Check shell permission
15056        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15057            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15058                    targetUserId)) {
15059                throw new SecurityException("Shell does not have permission to access user "
15060                        + targetUserId + "\n " + Debug.getCallers(3));
15061            }
15062        }
15063        return targetUserId;
15064    }
15065
15066    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15067            String className, int flags) {
15068        boolean result = false;
15069        // For apps that don't have pre-defined UIDs, check for permission
15070        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15071            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15072                if (ActivityManager.checkUidPermission(
15073                        INTERACT_ACROSS_USERS,
15074                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15075                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15076                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15077                            + " requests FLAG_SINGLE_USER, but app does not hold "
15078                            + INTERACT_ACROSS_USERS;
15079                    Slog.w(TAG, msg);
15080                    throw new SecurityException(msg);
15081                }
15082                // Permission passed
15083                result = true;
15084            }
15085        } else if ("system".equals(componentProcessName)) {
15086            result = true;
15087        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15088            // Phone app and persistent apps are allowed to export singleuser providers.
15089            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15090                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15091        }
15092        if (DEBUG_MU) {
15093            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15094                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15095        }
15096        return result;
15097    }
15098
15099    /**
15100     * Checks to see if the caller is in the same app as the singleton
15101     * component, or the component is in a special app. It allows special apps
15102     * to export singleton components but prevents exporting singleton
15103     * components for regular apps.
15104     */
15105    boolean isValidSingletonCall(int callingUid, int componentUid) {
15106        int componentAppId = UserHandle.getAppId(componentUid);
15107        return UserHandle.isSameApp(callingUid, componentUid)
15108                || componentAppId == Process.SYSTEM_UID
15109                || componentAppId == Process.PHONE_UID
15110                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15111                        == PackageManager.PERMISSION_GRANTED;
15112    }
15113
15114    public int bindService(IApplicationThread caller, IBinder token,
15115            Intent service, String resolvedType,
15116            IServiceConnection connection, int flags, int userId) {
15117        enforceNotIsolatedCaller("bindService");
15118
15119        // Refuse possible leaked file descriptors
15120        if (service != null && service.hasFileDescriptors() == true) {
15121            throw new IllegalArgumentException("File descriptors passed in Intent");
15122        }
15123
15124        synchronized(this) {
15125            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15126                    connection, flags, userId);
15127        }
15128    }
15129
15130    public boolean unbindService(IServiceConnection connection) {
15131        synchronized (this) {
15132            return mServices.unbindServiceLocked(connection);
15133        }
15134    }
15135
15136    public void publishService(IBinder token, Intent intent, IBinder service) {
15137        // Refuse possible leaked file descriptors
15138        if (intent != null && intent.hasFileDescriptors() == true) {
15139            throw new IllegalArgumentException("File descriptors passed in Intent");
15140        }
15141
15142        synchronized(this) {
15143            if (!(token instanceof ServiceRecord)) {
15144                throw new IllegalArgumentException("Invalid service token");
15145            }
15146            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15147        }
15148    }
15149
15150    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15151        // Refuse possible leaked file descriptors
15152        if (intent != null && intent.hasFileDescriptors() == true) {
15153            throw new IllegalArgumentException("File descriptors passed in Intent");
15154        }
15155
15156        synchronized(this) {
15157            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15158        }
15159    }
15160
15161    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15162        synchronized(this) {
15163            if (!(token instanceof ServiceRecord)) {
15164                throw new IllegalArgumentException("Invalid service token");
15165            }
15166            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15167        }
15168    }
15169
15170    // =========================================================
15171    // BACKUP AND RESTORE
15172    // =========================================================
15173
15174    // Cause the target app to be launched if necessary and its backup agent
15175    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15176    // activity manager to announce its creation.
15177    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15178        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15179        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15180
15181        synchronized(this) {
15182            // !!! TODO: currently no check here that we're already bound
15183            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15184            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15185            synchronized (stats) {
15186                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15187            }
15188
15189            // Backup agent is now in use, its package can't be stopped.
15190            try {
15191                AppGlobals.getPackageManager().setPackageStoppedState(
15192                        app.packageName, false, UserHandle.getUserId(app.uid));
15193            } catch (RemoteException e) {
15194            } catch (IllegalArgumentException e) {
15195                Slog.w(TAG, "Failed trying to unstop package "
15196                        + app.packageName + ": " + e);
15197            }
15198
15199            BackupRecord r = new BackupRecord(ss, app, backupMode);
15200            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15201                    ? new ComponentName(app.packageName, app.backupAgentName)
15202                    : new ComponentName("android", "FullBackupAgent");
15203            // startProcessLocked() returns existing proc's record if it's already running
15204            ProcessRecord proc = startProcessLocked(app.processName, app,
15205                    false, 0, "backup", hostingName, false, false, false);
15206            if (proc == null) {
15207                Slog.e(TAG, "Unable to start backup agent process " + r);
15208                return false;
15209            }
15210
15211            r.app = proc;
15212            mBackupTarget = r;
15213            mBackupAppName = app.packageName;
15214
15215            // Try not to kill the process during backup
15216            updateOomAdjLocked(proc);
15217
15218            // If the process is already attached, schedule the creation of the backup agent now.
15219            // If it is not yet live, this will be done when it attaches to the framework.
15220            if (proc.thread != null) {
15221                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15222                try {
15223                    proc.thread.scheduleCreateBackupAgent(app,
15224                            compatibilityInfoForPackageLocked(app), backupMode);
15225                } catch (RemoteException e) {
15226                    // Will time out on the backup manager side
15227                }
15228            } else {
15229                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15230            }
15231            // Invariants: at this point, the target app process exists and the application
15232            // is either already running or in the process of coming up.  mBackupTarget and
15233            // mBackupAppName describe the app, so that when it binds back to the AM we
15234            // know that it's scheduled for a backup-agent operation.
15235        }
15236
15237        return true;
15238    }
15239
15240    @Override
15241    public void clearPendingBackup() {
15242        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15243        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15244
15245        synchronized (this) {
15246            mBackupTarget = null;
15247            mBackupAppName = null;
15248        }
15249    }
15250
15251    // A backup agent has just come up
15252    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15253        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15254                + " = " + agent);
15255
15256        synchronized(this) {
15257            if (!agentPackageName.equals(mBackupAppName)) {
15258                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15259                return;
15260            }
15261        }
15262
15263        long oldIdent = Binder.clearCallingIdentity();
15264        try {
15265            IBackupManager bm = IBackupManager.Stub.asInterface(
15266                    ServiceManager.getService(Context.BACKUP_SERVICE));
15267            bm.agentConnected(agentPackageName, agent);
15268        } catch (RemoteException e) {
15269            // can't happen; the backup manager service is local
15270        } catch (Exception e) {
15271            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15272            e.printStackTrace();
15273        } finally {
15274            Binder.restoreCallingIdentity(oldIdent);
15275        }
15276    }
15277
15278    // done with this agent
15279    public void unbindBackupAgent(ApplicationInfo appInfo) {
15280        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15281        if (appInfo == null) {
15282            Slog.w(TAG, "unbind backup agent for null app");
15283            return;
15284        }
15285
15286        synchronized(this) {
15287            try {
15288                if (mBackupAppName == null) {
15289                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15290                    return;
15291                }
15292
15293                if (!mBackupAppName.equals(appInfo.packageName)) {
15294                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15295                    return;
15296                }
15297
15298                // Not backing this app up any more; reset its OOM adjustment
15299                final ProcessRecord proc = mBackupTarget.app;
15300                updateOomAdjLocked(proc);
15301
15302                // If the app crashed during backup, 'thread' will be null here
15303                if (proc.thread != null) {
15304                    try {
15305                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15306                                compatibilityInfoForPackageLocked(appInfo));
15307                    } catch (Exception e) {
15308                        Slog.e(TAG, "Exception when unbinding backup agent:");
15309                        e.printStackTrace();
15310                    }
15311                }
15312            } finally {
15313                mBackupTarget = null;
15314                mBackupAppName = null;
15315            }
15316        }
15317    }
15318    // =========================================================
15319    // BROADCASTS
15320    // =========================================================
15321
15322    private final List getStickiesLocked(String action, IntentFilter filter,
15323            List cur, int userId) {
15324        final ContentResolver resolver = mContext.getContentResolver();
15325        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15326        if (stickies == null) {
15327            return cur;
15328        }
15329        final ArrayList<Intent> list = stickies.get(action);
15330        if (list == null) {
15331            return cur;
15332        }
15333        int N = list.size();
15334        for (int i=0; i<N; i++) {
15335            Intent intent = list.get(i);
15336            if (filter.match(resolver, intent, true, TAG) >= 0) {
15337                if (cur == null) {
15338                    cur = new ArrayList<Intent>();
15339                }
15340                cur.add(intent);
15341            }
15342        }
15343        return cur;
15344    }
15345
15346    boolean isPendingBroadcastProcessLocked(int pid) {
15347        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15348                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15349    }
15350
15351    void skipPendingBroadcastLocked(int pid) {
15352            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15353            for (BroadcastQueue queue : mBroadcastQueues) {
15354                queue.skipPendingBroadcastLocked(pid);
15355            }
15356    }
15357
15358    // The app just attached; send any pending broadcasts that it should receive
15359    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15360        boolean didSomething = false;
15361        for (BroadcastQueue queue : mBroadcastQueues) {
15362            didSomething |= queue.sendPendingBroadcastsLocked(app);
15363        }
15364        return didSomething;
15365    }
15366
15367    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15368            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15369        enforceNotIsolatedCaller("registerReceiver");
15370        int callingUid;
15371        int callingPid;
15372        synchronized(this) {
15373            ProcessRecord callerApp = null;
15374            if (caller != null) {
15375                callerApp = getRecordForAppLocked(caller);
15376                if (callerApp == null) {
15377                    throw new SecurityException(
15378                            "Unable to find app for caller " + caller
15379                            + " (pid=" + Binder.getCallingPid()
15380                            + ") when registering receiver " + receiver);
15381                }
15382                if (callerApp.info.uid != Process.SYSTEM_UID &&
15383                        !callerApp.pkgList.containsKey(callerPackage) &&
15384                        !"android".equals(callerPackage)) {
15385                    throw new SecurityException("Given caller package " + callerPackage
15386                            + " is not running in process " + callerApp);
15387                }
15388                callingUid = callerApp.info.uid;
15389                callingPid = callerApp.pid;
15390            } else {
15391                callerPackage = null;
15392                callingUid = Binder.getCallingUid();
15393                callingPid = Binder.getCallingPid();
15394            }
15395
15396            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15397                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15398
15399            List allSticky = null;
15400
15401            // Look for any matching sticky broadcasts...
15402            Iterator actions = filter.actionsIterator();
15403            if (actions != null) {
15404                while (actions.hasNext()) {
15405                    String action = (String)actions.next();
15406                    allSticky = getStickiesLocked(action, filter, allSticky,
15407                            UserHandle.USER_ALL);
15408                    allSticky = getStickiesLocked(action, filter, allSticky,
15409                            UserHandle.getUserId(callingUid));
15410                }
15411            } else {
15412                allSticky = getStickiesLocked(null, filter, allSticky,
15413                        UserHandle.USER_ALL);
15414                allSticky = getStickiesLocked(null, filter, allSticky,
15415                        UserHandle.getUserId(callingUid));
15416            }
15417
15418            // The first sticky in the list is returned directly back to
15419            // the client.
15420            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15421
15422            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15423                    + ": " + sticky);
15424
15425            if (receiver == null) {
15426                return sticky;
15427            }
15428
15429            ReceiverList rl
15430                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15431            if (rl == null) {
15432                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15433                        userId, receiver);
15434                if (rl.app != null) {
15435                    rl.app.receivers.add(rl);
15436                } else {
15437                    try {
15438                        receiver.asBinder().linkToDeath(rl, 0);
15439                    } catch (RemoteException e) {
15440                        return sticky;
15441                    }
15442                    rl.linkedToDeath = true;
15443                }
15444                mRegisteredReceivers.put(receiver.asBinder(), rl);
15445            } else if (rl.uid != callingUid) {
15446                throw new IllegalArgumentException(
15447                        "Receiver requested to register for uid " + callingUid
15448                        + " was previously registered for uid " + rl.uid);
15449            } else if (rl.pid != callingPid) {
15450                throw new IllegalArgumentException(
15451                        "Receiver requested to register for pid " + callingPid
15452                        + " was previously registered for pid " + rl.pid);
15453            } else if (rl.userId != userId) {
15454                throw new IllegalArgumentException(
15455                        "Receiver requested to register for user " + userId
15456                        + " was previously registered for user " + rl.userId);
15457            }
15458            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15459                    permission, callingUid, userId);
15460            rl.add(bf);
15461            if (!bf.debugCheck()) {
15462                Slog.w(TAG, "==> For Dynamic broadast");
15463            }
15464            mReceiverResolver.addFilter(bf);
15465
15466            // Enqueue broadcasts for all existing stickies that match
15467            // this filter.
15468            if (allSticky != null) {
15469                ArrayList receivers = new ArrayList();
15470                receivers.add(bf);
15471
15472                int N = allSticky.size();
15473                for (int i=0; i<N; i++) {
15474                    Intent intent = (Intent)allSticky.get(i);
15475                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15476                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15477                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15478                            null, null, false, true, true, -1);
15479                    queue.enqueueParallelBroadcastLocked(r);
15480                    queue.scheduleBroadcastsLocked();
15481                }
15482            }
15483
15484            return sticky;
15485        }
15486    }
15487
15488    public void unregisterReceiver(IIntentReceiver receiver) {
15489        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15490
15491        final long origId = Binder.clearCallingIdentity();
15492        try {
15493            boolean doTrim = false;
15494
15495            synchronized(this) {
15496                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15497                if (rl != null) {
15498                    if (rl.curBroadcast != null) {
15499                        BroadcastRecord r = rl.curBroadcast;
15500                        final boolean doNext = finishReceiverLocked(
15501                                receiver.asBinder(), r.resultCode, r.resultData,
15502                                r.resultExtras, r.resultAbort);
15503                        if (doNext) {
15504                            doTrim = true;
15505                            r.queue.processNextBroadcast(false);
15506                        }
15507                    }
15508
15509                    if (rl.app != null) {
15510                        rl.app.receivers.remove(rl);
15511                    }
15512                    removeReceiverLocked(rl);
15513                    if (rl.linkedToDeath) {
15514                        rl.linkedToDeath = false;
15515                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15516                    }
15517                }
15518            }
15519
15520            // If we actually concluded any broadcasts, we might now be able
15521            // to trim the recipients' apps from our working set
15522            if (doTrim) {
15523                trimApplications();
15524                return;
15525            }
15526
15527        } finally {
15528            Binder.restoreCallingIdentity(origId);
15529        }
15530    }
15531
15532    void removeReceiverLocked(ReceiverList rl) {
15533        mRegisteredReceivers.remove(rl.receiver.asBinder());
15534        int N = rl.size();
15535        for (int i=0; i<N; i++) {
15536            mReceiverResolver.removeFilter(rl.get(i));
15537        }
15538    }
15539
15540    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15541        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15542            ProcessRecord r = mLruProcesses.get(i);
15543            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15544                try {
15545                    r.thread.dispatchPackageBroadcast(cmd, packages);
15546                } catch (RemoteException ex) {
15547                }
15548            }
15549        }
15550    }
15551
15552    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15553            int callingUid, int[] users) {
15554        List<ResolveInfo> receivers = null;
15555        try {
15556            HashSet<ComponentName> singleUserReceivers = null;
15557            boolean scannedFirstReceivers = false;
15558            for (int user : users) {
15559                // Skip users that have Shell restrictions
15560                if (callingUid == Process.SHELL_UID
15561                        && getUserManagerLocked().hasUserRestriction(
15562                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15563                    continue;
15564                }
15565                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15566                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15567                if (user != 0 && newReceivers != null) {
15568                    // If this is not the primary user, we need to check for
15569                    // any receivers that should be filtered out.
15570                    for (int i=0; i<newReceivers.size(); i++) {
15571                        ResolveInfo ri = newReceivers.get(i);
15572                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15573                            newReceivers.remove(i);
15574                            i--;
15575                        }
15576                    }
15577                }
15578                if (newReceivers != null && newReceivers.size() == 0) {
15579                    newReceivers = null;
15580                }
15581                if (receivers == null) {
15582                    receivers = newReceivers;
15583                } else if (newReceivers != null) {
15584                    // We need to concatenate the additional receivers
15585                    // found with what we have do far.  This would be easy,
15586                    // but we also need to de-dup any receivers that are
15587                    // singleUser.
15588                    if (!scannedFirstReceivers) {
15589                        // Collect any single user receivers we had already retrieved.
15590                        scannedFirstReceivers = true;
15591                        for (int i=0; i<receivers.size(); i++) {
15592                            ResolveInfo ri = receivers.get(i);
15593                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15594                                ComponentName cn = new ComponentName(
15595                                        ri.activityInfo.packageName, ri.activityInfo.name);
15596                                if (singleUserReceivers == null) {
15597                                    singleUserReceivers = new HashSet<ComponentName>();
15598                                }
15599                                singleUserReceivers.add(cn);
15600                            }
15601                        }
15602                    }
15603                    // Add the new results to the existing results, tracking
15604                    // and de-dupping single user receivers.
15605                    for (int i=0; i<newReceivers.size(); i++) {
15606                        ResolveInfo ri = newReceivers.get(i);
15607                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15608                            ComponentName cn = new ComponentName(
15609                                    ri.activityInfo.packageName, ri.activityInfo.name);
15610                            if (singleUserReceivers == null) {
15611                                singleUserReceivers = new HashSet<ComponentName>();
15612                            }
15613                            if (!singleUserReceivers.contains(cn)) {
15614                                singleUserReceivers.add(cn);
15615                                receivers.add(ri);
15616                            }
15617                        } else {
15618                            receivers.add(ri);
15619                        }
15620                    }
15621                }
15622            }
15623        } catch (RemoteException ex) {
15624            // pm is in same process, this will never happen.
15625        }
15626        return receivers;
15627    }
15628
15629    private final int broadcastIntentLocked(ProcessRecord callerApp,
15630            String callerPackage, Intent intent, String resolvedType,
15631            IIntentReceiver resultTo, int resultCode, String resultData,
15632            Bundle map, String requiredPermission, int appOp,
15633            boolean ordered, boolean sticky, int callingPid, int callingUid,
15634            int userId) {
15635        intent = new Intent(intent);
15636
15637        // By default broadcasts do not go to stopped apps.
15638        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15639
15640        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15641            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15642            + " ordered=" + ordered + " userid=" + userId);
15643        if ((resultTo != null) && !ordered) {
15644            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15645        }
15646
15647        userId = handleIncomingUser(callingPid, callingUid, userId,
15648                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15649
15650        // Make sure that the user who is receiving this broadcast is running.
15651        // If not, we will just skip it.
15652
15653        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15654            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15655                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15656                Slog.w(TAG, "Skipping broadcast of " + intent
15657                        + ": user " + userId + " is stopped");
15658                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15659            }
15660        }
15661
15662        /*
15663         * Prevent non-system code (defined here to be non-persistent
15664         * processes) from sending protected broadcasts.
15665         */
15666        int callingAppId = UserHandle.getAppId(callingUid);
15667        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15668            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15669            || callingAppId == Process.NFC_UID || callingUid == 0) {
15670            // Always okay.
15671        } else if (callerApp == null || !callerApp.persistent) {
15672            try {
15673                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15674                        intent.getAction())) {
15675                    String msg = "Permission Denial: not allowed to send broadcast "
15676                            + intent.getAction() + " from pid="
15677                            + callingPid + ", uid=" + callingUid;
15678                    Slog.w(TAG, msg);
15679                    throw new SecurityException(msg);
15680                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15681                    // Special case for compatibility: we don't want apps to send this,
15682                    // but historically it has not been protected and apps may be using it
15683                    // to poke their own app widget.  So, instead of making it protected,
15684                    // just limit it to the caller.
15685                    if (callerApp == null) {
15686                        String msg = "Permission Denial: not allowed to send broadcast "
15687                                + intent.getAction() + " from unknown caller.";
15688                        Slog.w(TAG, msg);
15689                        throw new SecurityException(msg);
15690                    } else if (intent.getComponent() != null) {
15691                        // They are good enough to send to an explicit component...  verify
15692                        // it is being sent to the calling app.
15693                        if (!intent.getComponent().getPackageName().equals(
15694                                callerApp.info.packageName)) {
15695                            String msg = "Permission Denial: not allowed to send broadcast "
15696                                    + intent.getAction() + " to "
15697                                    + intent.getComponent().getPackageName() + " from "
15698                                    + callerApp.info.packageName;
15699                            Slog.w(TAG, msg);
15700                            throw new SecurityException(msg);
15701                        }
15702                    } else {
15703                        // Limit broadcast to their own package.
15704                        intent.setPackage(callerApp.info.packageName);
15705                    }
15706                }
15707            } catch (RemoteException e) {
15708                Slog.w(TAG, "Remote exception", e);
15709                return ActivityManager.BROADCAST_SUCCESS;
15710            }
15711        }
15712
15713        final String action = intent.getAction();
15714        if (action != null) {
15715            switch (action) {
15716                case Intent.ACTION_UID_REMOVED:
15717                case Intent.ACTION_PACKAGE_REMOVED:
15718                case Intent.ACTION_PACKAGE_CHANGED:
15719                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15720                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15721                    // Handle special intents: if this broadcast is from the package
15722                    // manager about a package being removed, we need to remove all of
15723                    // its activities from the history stack.
15724                    if (checkComponentPermission(
15725                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15726                            callingPid, callingUid, -1, true)
15727                            != PackageManager.PERMISSION_GRANTED) {
15728                        String msg = "Permission Denial: " + intent.getAction()
15729                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15730                                + ", uid=" + callingUid + ")"
15731                                + " requires "
15732                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15733                        Slog.w(TAG, msg);
15734                        throw new SecurityException(msg);
15735                    }
15736                    switch (action) {
15737                        case Intent.ACTION_UID_REMOVED:
15738                            final Bundle intentExtras = intent.getExtras();
15739                            final int uid = intentExtras != null
15740                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15741                            if (uid >= 0) {
15742                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15743                                synchronized (bs) {
15744                                    bs.removeUidStatsLocked(uid);
15745                                }
15746                                mAppOpsService.uidRemoved(uid);
15747                            }
15748                            break;
15749                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15750                            // If resources are unavailable just force stop all those packages
15751                            // and flush the attribute cache as well.
15752                            String list[] =
15753                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15754                            if (list != null && list.length > 0) {
15755                                for (int i = 0; i < list.length; i++) {
15756                                    forceStopPackageLocked(list[i], -1, false, true, true,
15757                                            false, false, userId, "storage unmount");
15758                                }
15759                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15760                                sendPackageBroadcastLocked(
15761                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15762                                        userId);
15763                            }
15764                            break;
15765                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15766                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15767                            break;
15768                        case Intent.ACTION_PACKAGE_REMOVED:
15769                        case Intent.ACTION_PACKAGE_CHANGED:
15770                            Uri data = intent.getData();
15771                            String ssp;
15772                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15773                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15774                                boolean fullUninstall = removed &&
15775                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15776                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15777                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15778                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15779                                            false, true, true, false, fullUninstall, userId,
15780                                            removed ? "pkg removed" : "pkg changed");
15781                                }
15782                                if (removed) {
15783                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15784                                            new String[] {ssp}, userId);
15785                                    if (fullUninstall) {
15786                                        mAppOpsService.packageRemoved(
15787                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15788
15789                                        // Remove all permissions granted from/to this package
15790                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15791
15792                                        removeTasksByPackageNameLocked(ssp, userId);
15793                                    }
15794                                } else {
15795                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15796                                }
15797                            }
15798                            break;
15799                    }
15800                    break;
15801                case Intent.ACTION_PACKAGE_ADDED:
15802                    // Special case for adding a package: by default turn on compatibility mode.
15803                    Uri data = intent.getData();
15804                    String ssp;
15805                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15806                        final boolean replacing =
15807                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15808                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15809
15810                        if (replacing) {
15811                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15812                        }
15813                    }
15814                    break;
15815                case Intent.ACTION_TIMEZONE_CHANGED:
15816                    // If this is the time zone changed action, queue up a message that will reset
15817                    // the timezone of all currently running processes. This message will get
15818                    // queued up before the broadcast happens.
15819                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15820                    break;
15821                case Intent.ACTION_TIME_CHANGED:
15822                    // If the user set the time, let all running processes know.
15823                    final int is24Hour =
15824                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15825                                    : 0;
15826                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15827                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15828                    synchronized (stats) {
15829                        stats.noteCurrentTimeChangedLocked();
15830                    }
15831                    break;
15832                case Intent.ACTION_CLEAR_DNS_CACHE:
15833                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15834                    break;
15835                case Proxy.PROXY_CHANGE_ACTION:
15836                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15837                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15838                    break;
15839            }
15840        }
15841
15842        // Add to the sticky list if requested.
15843        if (sticky) {
15844            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15845                    callingPid, callingUid)
15846                    != PackageManager.PERMISSION_GRANTED) {
15847                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15848                        + callingPid + ", uid=" + callingUid
15849                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15850                Slog.w(TAG, msg);
15851                throw new SecurityException(msg);
15852            }
15853            if (requiredPermission != null) {
15854                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15855                        + " and enforce permission " + requiredPermission);
15856                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15857            }
15858            if (intent.getComponent() != null) {
15859                throw new SecurityException(
15860                        "Sticky broadcasts can't target a specific component");
15861            }
15862            // We use userId directly here, since the "all" target is maintained
15863            // as a separate set of sticky broadcasts.
15864            if (userId != UserHandle.USER_ALL) {
15865                // But first, if this is not a broadcast to all users, then
15866                // make sure it doesn't conflict with an existing broadcast to
15867                // all users.
15868                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15869                        UserHandle.USER_ALL);
15870                if (stickies != null) {
15871                    ArrayList<Intent> list = stickies.get(intent.getAction());
15872                    if (list != null) {
15873                        int N = list.size();
15874                        int i;
15875                        for (i=0; i<N; i++) {
15876                            if (intent.filterEquals(list.get(i))) {
15877                                throw new IllegalArgumentException(
15878                                        "Sticky broadcast " + intent + " for user "
15879                                        + userId + " conflicts with existing global broadcast");
15880                            }
15881                        }
15882                    }
15883                }
15884            }
15885            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15886            if (stickies == null) {
15887                stickies = new ArrayMap<String, ArrayList<Intent>>();
15888                mStickyBroadcasts.put(userId, stickies);
15889            }
15890            ArrayList<Intent> list = stickies.get(intent.getAction());
15891            if (list == null) {
15892                list = new ArrayList<Intent>();
15893                stickies.put(intent.getAction(), list);
15894            }
15895            int N = list.size();
15896            int i;
15897            for (i=0; i<N; i++) {
15898                if (intent.filterEquals(list.get(i))) {
15899                    // This sticky already exists, replace it.
15900                    list.set(i, new Intent(intent));
15901                    break;
15902                }
15903            }
15904            if (i >= N) {
15905                list.add(new Intent(intent));
15906            }
15907        }
15908
15909        int[] users;
15910        if (userId == UserHandle.USER_ALL) {
15911            // Caller wants broadcast to go to all started users.
15912            users = mStartedUserArray;
15913        } else {
15914            // Caller wants broadcast to go to one specific user.
15915            users = new int[] {userId};
15916        }
15917
15918        // Figure out who all will receive this broadcast.
15919        List receivers = null;
15920        List<BroadcastFilter> registeredReceivers = null;
15921        // Need to resolve the intent to interested receivers...
15922        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15923                 == 0) {
15924            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15925        }
15926        if (intent.getComponent() == null) {
15927            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15928                // Query one target user at a time, excluding shell-restricted users
15929                UserManagerService ums = getUserManagerLocked();
15930                for (int i = 0; i < users.length; i++) {
15931                    if (ums.hasUserRestriction(
15932                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15933                        continue;
15934                    }
15935                    List<BroadcastFilter> registeredReceiversForUser =
15936                            mReceiverResolver.queryIntent(intent,
15937                                    resolvedType, false, users[i]);
15938                    if (registeredReceivers == null) {
15939                        registeredReceivers = registeredReceiversForUser;
15940                    } else if (registeredReceiversForUser != null) {
15941                        registeredReceivers.addAll(registeredReceiversForUser);
15942                    }
15943                }
15944            } else {
15945                registeredReceivers = mReceiverResolver.queryIntent(intent,
15946                        resolvedType, false, userId);
15947            }
15948        }
15949
15950        final boolean replacePending =
15951                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15952
15953        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15954                + " replacePending=" + replacePending);
15955
15956        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15957        if (!ordered && NR > 0) {
15958            // If we are not serializing this broadcast, then send the
15959            // registered receivers separately so they don't wait for the
15960            // components to be launched.
15961            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15962            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15963                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15964                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15965                    ordered, sticky, false, userId);
15966            if (DEBUG_BROADCAST) Slog.v(
15967                    TAG, "Enqueueing parallel broadcast " + r);
15968            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15969            if (!replaced) {
15970                queue.enqueueParallelBroadcastLocked(r);
15971                queue.scheduleBroadcastsLocked();
15972            }
15973            registeredReceivers = null;
15974            NR = 0;
15975        }
15976
15977        // Merge into one list.
15978        int ir = 0;
15979        if (receivers != null) {
15980            // A special case for PACKAGE_ADDED: do not allow the package
15981            // being added to see this broadcast.  This prevents them from
15982            // using this as a back door to get run as soon as they are
15983            // installed.  Maybe in the future we want to have a special install
15984            // broadcast or such for apps, but we'd like to deliberately make
15985            // this decision.
15986            String skipPackages[] = null;
15987            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15988                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15989                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15990                Uri data = intent.getData();
15991                if (data != null) {
15992                    String pkgName = data.getSchemeSpecificPart();
15993                    if (pkgName != null) {
15994                        skipPackages = new String[] { pkgName };
15995                    }
15996                }
15997            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15998                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15999            }
16000            if (skipPackages != null && (skipPackages.length > 0)) {
16001                for (String skipPackage : skipPackages) {
16002                    if (skipPackage != null) {
16003                        int NT = receivers.size();
16004                        for (int it=0; it<NT; it++) {
16005                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16006                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16007                                receivers.remove(it);
16008                                it--;
16009                                NT--;
16010                            }
16011                        }
16012                    }
16013                }
16014            }
16015
16016            int NT = receivers != null ? receivers.size() : 0;
16017            int it = 0;
16018            ResolveInfo curt = null;
16019            BroadcastFilter curr = null;
16020            while (it < NT && ir < NR) {
16021                if (curt == null) {
16022                    curt = (ResolveInfo)receivers.get(it);
16023                }
16024                if (curr == null) {
16025                    curr = registeredReceivers.get(ir);
16026                }
16027                if (curr.getPriority() >= curt.priority) {
16028                    // Insert this broadcast record into the final list.
16029                    receivers.add(it, curr);
16030                    ir++;
16031                    curr = null;
16032                    it++;
16033                    NT++;
16034                } else {
16035                    // Skip to the next ResolveInfo in the final list.
16036                    it++;
16037                    curt = null;
16038                }
16039            }
16040        }
16041        while (ir < NR) {
16042            if (receivers == null) {
16043                receivers = new ArrayList();
16044            }
16045            receivers.add(registeredReceivers.get(ir));
16046            ir++;
16047        }
16048
16049        if ((receivers != null && receivers.size() > 0)
16050                || resultTo != null) {
16051            BroadcastQueue queue = broadcastQueueForIntent(intent);
16052            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16053                    callerPackage, callingPid, callingUid, resolvedType,
16054                    requiredPermission, appOp, receivers, resultTo, resultCode,
16055                    resultData, map, ordered, sticky, false, userId);
16056            if (DEBUG_BROADCAST) Slog.v(
16057                    TAG, "Enqueueing ordered broadcast " + r
16058                    + ": prev had " + queue.mOrderedBroadcasts.size());
16059            if (DEBUG_BROADCAST) {
16060                int seq = r.intent.getIntExtra("seq", -1);
16061                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16062            }
16063            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16064            if (!replaced) {
16065                queue.enqueueOrderedBroadcastLocked(r);
16066                queue.scheduleBroadcastsLocked();
16067            }
16068        }
16069
16070        return ActivityManager.BROADCAST_SUCCESS;
16071    }
16072
16073    final Intent verifyBroadcastLocked(Intent intent) {
16074        // Refuse possible leaked file descriptors
16075        if (intent != null && intent.hasFileDescriptors() == true) {
16076            throw new IllegalArgumentException("File descriptors passed in Intent");
16077        }
16078
16079        int flags = intent.getFlags();
16080
16081        if (!mProcessesReady) {
16082            // if the caller really truly claims to know what they're doing, go
16083            // ahead and allow the broadcast without launching any receivers
16084            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16085                intent = new Intent(intent);
16086                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16087            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16088                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16089                        + " before boot completion");
16090                throw new IllegalStateException("Cannot broadcast before boot completed");
16091            }
16092        }
16093
16094        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16095            throw new IllegalArgumentException(
16096                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16097        }
16098
16099        return intent;
16100    }
16101
16102    public final int broadcastIntent(IApplicationThread caller,
16103            Intent intent, String resolvedType, IIntentReceiver resultTo,
16104            int resultCode, String resultData, Bundle map,
16105            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16106        enforceNotIsolatedCaller("broadcastIntent");
16107        synchronized(this) {
16108            intent = verifyBroadcastLocked(intent);
16109
16110            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16111            final int callingPid = Binder.getCallingPid();
16112            final int callingUid = Binder.getCallingUid();
16113            final long origId = Binder.clearCallingIdentity();
16114            int res = broadcastIntentLocked(callerApp,
16115                    callerApp != null ? callerApp.info.packageName : null,
16116                    intent, resolvedType, resultTo,
16117                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16118                    callingPid, callingUid, userId);
16119            Binder.restoreCallingIdentity(origId);
16120            return res;
16121        }
16122    }
16123
16124    int broadcastIntentInPackage(String packageName, int uid,
16125            Intent intent, String resolvedType, IIntentReceiver resultTo,
16126            int resultCode, String resultData, Bundle map,
16127            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16128        synchronized(this) {
16129            intent = verifyBroadcastLocked(intent);
16130
16131            final long origId = Binder.clearCallingIdentity();
16132            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16133                    resultTo, resultCode, resultData, map, requiredPermission,
16134                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16135            Binder.restoreCallingIdentity(origId);
16136            return res;
16137        }
16138    }
16139
16140    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16141        // Refuse possible leaked file descriptors
16142        if (intent != null && intent.hasFileDescriptors() == true) {
16143            throw new IllegalArgumentException("File descriptors passed in Intent");
16144        }
16145
16146        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16147                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16148
16149        synchronized(this) {
16150            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16151                    != PackageManager.PERMISSION_GRANTED) {
16152                String msg = "Permission Denial: unbroadcastIntent() from pid="
16153                        + Binder.getCallingPid()
16154                        + ", uid=" + Binder.getCallingUid()
16155                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16156                Slog.w(TAG, msg);
16157                throw new SecurityException(msg);
16158            }
16159            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16160            if (stickies != null) {
16161                ArrayList<Intent> list = stickies.get(intent.getAction());
16162                if (list != null) {
16163                    int N = list.size();
16164                    int i;
16165                    for (i=0; i<N; i++) {
16166                        if (intent.filterEquals(list.get(i))) {
16167                            list.remove(i);
16168                            break;
16169                        }
16170                    }
16171                    if (list.size() <= 0) {
16172                        stickies.remove(intent.getAction());
16173                    }
16174                }
16175                if (stickies.size() <= 0) {
16176                    mStickyBroadcasts.remove(userId);
16177                }
16178            }
16179        }
16180    }
16181
16182    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16183            String resultData, Bundle resultExtras, boolean resultAbort) {
16184        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16185        if (r == null) {
16186            Slog.w(TAG, "finishReceiver called but not found on queue");
16187            return false;
16188        }
16189
16190        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16191    }
16192
16193    void backgroundServicesFinishedLocked(int userId) {
16194        for (BroadcastQueue queue : mBroadcastQueues) {
16195            queue.backgroundServicesFinishedLocked(userId);
16196        }
16197    }
16198
16199    public void finishReceiver(IBinder who, int resultCode, String resultData,
16200            Bundle resultExtras, boolean resultAbort) {
16201        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16202
16203        // Refuse possible leaked file descriptors
16204        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16205            throw new IllegalArgumentException("File descriptors passed in Bundle");
16206        }
16207
16208        final long origId = Binder.clearCallingIdentity();
16209        try {
16210            boolean doNext = false;
16211            BroadcastRecord r;
16212
16213            synchronized(this) {
16214                r = broadcastRecordForReceiverLocked(who);
16215                if (r != null) {
16216                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16217                        resultData, resultExtras, resultAbort, true);
16218                }
16219            }
16220
16221            if (doNext) {
16222                r.queue.processNextBroadcast(false);
16223            }
16224            trimApplications();
16225        } finally {
16226            Binder.restoreCallingIdentity(origId);
16227        }
16228    }
16229
16230    // =========================================================
16231    // INSTRUMENTATION
16232    // =========================================================
16233
16234    public boolean startInstrumentation(ComponentName className,
16235            String profileFile, int flags, Bundle arguments,
16236            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16237            int userId, String abiOverride) {
16238        enforceNotIsolatedCaller("startInstrumentation");
16239        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16240                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16241        // Refuse possible leaked file descriptors
16242        if (arguments != null && arguments.hasFileDescriptors()) {
16243            throw new IllegalArgumentException("File descriptors passed in Bundle");
16244        }
16245
16246        synchronized(this) {
16247            InstrumentationInfo ii = null;
16248            ApplicationInfo ai = null;
16249            try {
16250                ii = mContext.getPackageManager().getInstrumentationInfo(
16251                    className, STOCK_PM_FLAGS);
16252                ai = AppGlobals.getPackageManager().getApplicationInfo(
16253                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16254            } catch (PackageManager.NameNotFoundException e) {
16255            } catch (RemoteException e) {
16256            }
16257            if (ii == null) {
16258                reportStartInstrumentationFailure(watcher, className,
16259                        "Unable to find instrumentation info for: " + className);
16260                return false;
16261            }
16262            if (ai == null) {
16263                reportStartInstrumentationFailure(watcher, className,
16264                        "Unable to find instrumentation target package: " + ii.targetPackage);
16265                return false;
16266            }
16267
16268            int match = mContext.getPackageManager().checkSignatures(
16269                    ii.targetPackage, ii.packageName);
16270            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16271                String msg = "Permission Denial: starting instrumentation "
16272                        + className + " from pid="
16273                        + Binder.getCallingPid()
16274                        + ", uid=" + Binder.getCallingPid()
16275                        + " not allowed because package " + ii.packageName
16276                        + " does not have a signature matching the target "
16277                        + ii.targetPackage;
16278                reportStartInstrumentationFailure(watcher, className, msg);
16279                throw new SecurityException(msg);
16280            }
16281
16282            final long origId = Binder.clearCallingIdentity();
16283            // Instrumentation can kill and relaunch even persistent processes
16284            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16285                    "start instr");
16286            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16287            app.instrumentationClass = className;
16288            app.instrumentationInfo = ai;
16289            app.instrumentationProfileFile = profileFile;
16290            app.instrumentationArguments = arguments;
16291            app.instrumentationWatcher = watcher;
16292            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16293            app.instrumentationResultClass = className;
16294            Binder.restoreCallingIdentity(origId);
16295        }
16296
16297        return true;
16298    }
16299
16300    /**
16301     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16302     * error to the logs, but if somebody is watching, send the report there too.  This enables
16303     * the "am" command to report errors with more information.
16304     *
16305     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16306     * @param cn The component name of the instrumentation.
16307     * @param report The error report.
16308     */
16309    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16310            ComponentName cn, String report) {
16311        Slog.w(TAG, report);
16312        try {
16313            if (watcher != null) {
16314                Bundle results = new Bundle();
16315                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16316                results.putString("Error", report);
16317                watcher.instrumentationStatus(cn, -1, results);
16318            }
16319        } catch (RemoteException e) {
16320            Slog.w(TAG, e);
16321        }
16322    }
16323
16324    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16325        if (app.instrumentationWatcher != null) {
16326            try {
16327                // NOTE:  IInstrumentationWatcher *must* be oneway here
16328                app.instrumentationWatcher.instrumentationFinished(
16329                    app.instrumentationClass,
16330                    resultCode,
16331                    results);
16332            } catch (RemoteException e) {
16333            }
16334        }
16335        if (app.instrumentationUiAutomationConnection != null) {
16336            try {
16337                app.instrumentationUiAutomationConnection.shutdown();
16338            } catch (RemoteException re) {
16339                /* ignore */
16340            }
16341            // Only a UiAutomation can set this flag and now that
16342            // it is finished we make sure it is reset to its default.
16343            mUserIsMonkey = false;
16344        }
16345        app.instrumentationWatcher = null;
16346        app.instrumentationUiAutomationConnection = null;
16347        app.instrumentationClass = null;
16348        app.instrumentationInfo = null;
16349        app.instrumentationProfileFile = null;
16350        app.instrumentationArguments = null;
16351
16352        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16353                "finished inst");
16354    }
16355
16356    public void finishInstrumentation(IApplicationThread target,
16357            int resultCode, Bundle results) {
16358        int userId = UserHandle.getCallingUserId();
16359        // Refuse possible leaked file descriptors
16360        if (results != null && results.hasFileDescriptors()) {
16361            throw new IllegalArgumentException("File descriptors passed in Intent");
16362        }
16363
16364        synchronized(this) {
16365            ProcessRecord app = getRecordForAppLocked(target);
16366            if (app == null) {
16367                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16368                return;
16369            }
16370            final long origId = Binder.clearCallingIdentity();
16371            finishInstrumentationLocked(app, resultCode, results);
16372            Binder.restoreCallingIdentity(origId);
16373        }
16374    }
16375
16376    // =========================================================
16377    // CONFIGURATION
16378    // =========================================================
16379
16380    public ConfigurationInfo getDeviceConfigurationInfo() {
16381        ConfigurationInfo config = new ConfigurationInfo();
16382        synchronized (this) {
16383            config.reqTouchScreen = mConfiguration.touchscreen;
16384            config.reqKeyboardType = mConfiguration.keyboard;
16385            config.reqNavigation = mConfiguration.navigation;
16386            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16387                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16388                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16389            }
16390            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16391                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16392                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16393            }
16394            config.reqGlEsVersion = GL_ES_VERSION;
16395        }
16396        return config;
16397    }
16398
16399    ActivityStack getFocusedStack() {
16400        return mStackSupervisor.getFocusedStack();
16401    }
16402
16403    public Configuration getConfiguration() {
16404        Configuration ci;
16405        synchronized(this) {
16406            ci = new Configuration(mConfiguration);
16407        }
16408        return ci;
16409    }
16410
16411    public void updatePersistentConfiguration(Configuration values) {
16412        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16413                "updateConfiguration()");
16414        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16415                "updateConfiguration()");
16416        if (values == null) {
16417            throw new NullPointerException("Configuration must not be null");
16418        }
16419
16420        synchronized(this) {
16421            final long origId = Binder.clearCallingIdentity();
16422            updateConfigurationLocked(values, null, true, false);
16423            Binder.restoreCallingIdentity(origId);
16424        }
16425    }
16426
16427    public void updateConfiguration(Configuration values) {
16428        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16429                "updateConfiguration()");
16430
16431        synchronized(this) {
16432            if (values == null && mWindowManager != null) {
16433                // sentinel: fetch the current configuration from the window manager
16434                values = mWindowManager.computeNewConfiguration();
16435            }
16436
16437            if (mWindowManager != null) {
16438                mProcessList.applyDisplaySize(mWindowManager);
16439            }
16440
16441            final long origId = Binder.clearCallingIdentity();
16442            if (values != null) {
16443                Settings.System.clearConfiguration(values);
16444            }
16445            updateConfigurationLocked(values, null, false, false);
16446            Binder.restoreCallingIdentity(origId);
16447        }
16448    }
16449
16450    /**
16451     * Do either or both things: (1) change the current configuration, and (2)
16452     * make sure the given activity is running with the (now) current
16453     * configuration.  Returns true if the activity has been left running, or
16454     * false if <var>starting</var> is being destroyed to match the new
16455     * configuration.
16456     * @param persistent TODO
16457     */
16458    boolean updateConfigurationLocked(Configuration values,
16459            ActivityRecord starting, boolean persistent, boolean initLocale) {
16460        int changes = 0;
16461
16462        if (values != null) {
16463            Configuration newConfig = new Configuration(mConfiguration);
16464            changes = newConfig.updateFrom(values);
16465            if (changes != 0) {
16466                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16467                    Slog.i(TAG, "Updating configuration to: " + values);
16468                }
16469
16470                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16471
16472                if (values.locale != null && !initLocale) {
16473                    saveLocaleLocked(values.locale,
16474                                     !values.locale.equals(mConfiguration.locale),
16475                                     values.userSetLocale);
16476                }
16477
16478                mConfigurationSeq++;
16479                if (mConfigurationSeq <= 0) {
16480                    mConfigurationSeq = 1;
16481                }
16482                newConfig.seq = mConfigurationSeq;
16483                mConfiguration = newConfig;
16484                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16485                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16486                //mUsageStatsService.noteStartConfig(newConfig);
16487
16488                final Configuration configCopy = new Configuration(mConfiguration);
16489
16490                // TODO: If our config changes, should we auto dismiss any currently
16491                // showing dialogs?
16492                mShowDialogs = shouldShowDialogs(newConfig);
16493
16494                AttributeCache ac = AttributeCache.instance();
16495                if (ac != null) {
16496                    ac.updateConfiguration(configCopy);
16497                }
16498
16499                // Make sure all resources in our process are updated
16500                // right now, so that anyone who is going to retrieve
16501                // resource values after we return will be sure to get
16502                // the new ones.  This is especially important during
16503                // boot, where the first config change needs to guarantee
16504                // all resources have that config before following boot
16505                // code is executed.
16506                mSystemThread.applyConfigurationToResources(configCopy);
16507
16508                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16509                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16510                    msg.obj = new Configuration(configCopy);
16511                    mHandler.sendMessage(msg);
16512                }
16513
16514                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16515                    ProcessRecord app = mLruProcesses.get(i);
16516                    try {
16517                        if (app.thread != null) {
16518                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16519                                    + app.processName + " new config " + mConfiguration);
16520                            app.thread.scheduleConfigurationChanged(configCopy);
16521                        }
16522                    } catch (Exception e) {
16523                    }
16524                }
16525                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16526                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16527                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16528                        | Intent.FLAG_RECEIVER_FOREGROUND);
16529                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16530                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16531                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16532                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16533                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16534                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16535                    broadcastIntentLocked(null, null, intent,
16536                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16537                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16538                }
16539            }
16540        }
16541
16542        boolean kept = true;
16543        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16544        // mainStack is null during startup.
16545        if (mainStack != null) {
16546            if (changes != 0 && starting == null) {
16547                // If the configuration changed, and the caller is not already
16548                // in the process of starting an activity, then find the top
16549                // activity to check if its configuration needs to change.
16550                starting = mainStack.topRunningActivityLocked(null);
16551            }
16552
16553            if (starting != null) {
16554                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16555                // And we need to make sure at this point that all other activities
16556                // are made visible with the correct configuration.
16557                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16558            }
16559        }
16560
16561        if (values != null && mWindowManager != null) {
16562            mWindowManager.setNewConfiguration(mConfiguration);
16563        }
16564
16565        return kept;
16566    }
16567
16568    /**
16569     * Decide based on the configuration whether we should shouw the ANR,
16570     * crash, etc dialogs.  The idea is that if there is no affordnace to
16571     * press the on-screen buttons, we shouldn't show the dialog.
16572     *
16573     * A thought: SystemUI might also want to get told about this, the Power
16574     * dialog / global actions also might want different behaviors.
16575     */
16576    private static final boolean shouldShowDialogs(Configuration config) {
16577        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16578                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16579    }
16580
16581    /**
16582     * Save the locale.  You must be inside a synchronized (this) block.
16583     */
16584    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16585        if(isDiff) {
16586            SystemProperties.set("user.language", l.getLanguage());
16587            SystemProperties.set("user.region", l.getCountry());
16588        }
16589
16590        if(isPersist) {
16591            SystemProperties.set("persist.sys.language", l.getLanguage());
16592            SystemProperties.set("persist.sys.country", l.getCountry());
16593            SystemProperties.set("persist.sys.localevar", l.getVariant());
16594
16595            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16596        }
16597    }
16598
16599    @Override
16600    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16601        synchronized (this) {
16602            ActivityRecord srec = ActivityRecord.forToken(token);
16603            if (srec.task != null && srec.task.stack != null) {
16604                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16605            }
16606        }
16607        return false;
16608    }
16609
16610    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16611            Intent resultData) {
16612
16613        synchronized (this) {
16614            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16615            if (stack != null) {
16616                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16617            }
16618            return false;
16619        }
16620    }
16621
16622    public int getLaunchedFromUid(IBinder activityToken) {
16623        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16624        if (srec == null) {
16625            return -1;
16626        }
16627        return srec.launchedFromUid;
16628    }
16629
16630    public String getLaunchedFromPackage(IBinder activityToken) {
16631        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16632        if (srec == null) {
16633            return null;
16634        }
16635        return srec.launchedFromPackage;
16636    }
16637
16638    // =========================================================
16639    // LIFETIME MANAGEMENT
16640    // =========================================================
16641
16642    // Returns which broadcast queue the app is the current [or imminent] receiver
16643    // on, or 'null' if the app is not an active broadcast recipient.
16644    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16645        BroadcastRecord r = app.curReceiver;
16646        if (r != null) {
16647            return r.queue;
16648        }
16649
16650        // It's not the current receiver, but it might be starting up to become one
16651        synchronized (this) {
16652            for (BroadcastQueue queue : mBroadcastQueues) {
16653                r = queue.mPendingBroadcast;
16654                if (r != null && r.curApp == app) {
16655                    // found it; report which queue it's in
16656                    return queue;
16657                }
16658            }
16659        }
16660
16661        return null;
16662    }
16663
16664    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16665            boolean doingAll, long now) {
16666        if (mAdjSeq == app.adjSeq) {
16667            // This adjustment has already been computed.
16668            return app.curRawAdj;
16669        }
16670
16671        if (app.thread == null) {
16672            app.adjSeq = mAdjSeq;
16673            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16674            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16675            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16676        }
16677
16678        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16679        app.adjSource = null;
16680        app.adjTarget = null;
16681        app.empty = false;
16682        app.cached = false;
16683
16684        final int activitiesSize = app.activities.size();
16685
16686        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16687            // The max adjustment doesn't allow this app to be anything
16688            // below foreground, so it is not worth doing work for it.
16689            app.adjType = "fixed";
16690            app.adjSeq = mAdjSeq;
16691            app.curRawAdj = app.maxAdj;
16692            app.foregroundActivities = false;
16693            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16694            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16695            // System processes can do UI, and when they do we want to have
16696            // them trim their memory after the user leaves the UI.  To
16697            // facilitate this, here we need to determine whether or not it
16698            // is currently showing UI.
16699            app.systemNoUi = true;
16700            if (app == TOP_APP) {
16701                app.systemNoUi = false;
16702            } else if (activitiesSize > 0) {
16703                for (int j = 0; j < activitiesSize; j++) {
16704                    final ActivityRecord r = app.activities.get(j);
16705                    if (r.visible) {
16706                        app.systemNoUi = false;
16707                    }
16708                }
16709            }
16710            if (!app.systemNoUi) {
16711                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16712            }
16713            return (app.curAdj=app.maxAdj);
16714        }
16715
16716        app.systemNoUi = false;
16717
16718        // Determine the importance of the process, starting with most
16719        // important to least, and assign an appropriate OOM adjustment.
16720        int adj;
16721        int schedGroup;
16722        int procState;
16723        boolean foregroundActivities = false;
16724        BroadcastQueue queue;
16725        if (app == TOP_APP) {
16726            // The last app on the list is the foreground app.
16727            adj = ProcessList.FOREGROUND_APP_ADJ;
16728            schedGroup = Process.THREAD_GROUP_DEFAULT;
16729            app.adjType = "top-activity";
16730            foregroundActivities = true;
16731            procState = ActivityManager.PROCESS_STATE_TOP;
16732        } else if (app.instrumentationClass != null) {
16733            // Don't want to kill running instrumentation.
16734            adj = ProcessList.FOREGROUND_APP_ADJ;
16735            schedGroup = Process.THREAD_GROUP_DEFAULT;
16736            app.adjType = "instrumentation";
16737            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16738        } else if ((queue = isReceivingBroadcast(app)) != null) {
16739            // An app that is currently receiving a broadcast also
16740            // counts as being in the foreground for OOM killer purposes.
16741            // It's placed in a sched group based on the nature of the
16742            // broadcast as reflected by which queue it's active in.
16743            adj = ProcessList.FOREGROUND_APP_ADJ;
16744            schedGroup = (queue == mFgBroadcastQueue)
16745                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16746            app.adjType = "broadcast";
16747            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16748        } else if (app.executingServices.size() > 0) {
16749            // An app that is currently executing a service callback also
16750            // counts as being in the foreground.
16751            adj = ProcessList.FOREGROUND_APP_ADJ;
16752            schedGroup = app.execServicesFg ?
16753                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16754            app.adjType = "exec-service";
16755            procState = ActivityManager.PROCESS_STATE_SERVICE;
16756            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16757        } else {
16758            // As far as we know the process is empty.  We may change our mind later.
16759            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16760            // At this point we don't actually know the adjustment.  Use the cached adj
16761            // value that the caller wants us to.
16762            adj = cachedAdj;
16763            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16764            app.cached = true;
16765            app.empty = true;
16766            app.adjType = "cch-empty";
16767        }
16768
16769        // Examine all activities if not already foreground.
16770        if (!foregroundActivities && activitiesSize > 0) {
16771            for (int j = 0; j < activitiesSize; j++) {
16772                final ActivityRecord r = app.activities.get(j);
16773                if (r.app != app) {
16774                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16775                            + app + "?!?");
16776                    continue;
16777                }
16778                if (r.visible) {
16779                    // App has a visible activity; only upgrade adjustment.
16780                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16781                        adj = ProcessList.VISIBLE_APP_ADJ;
16782                        app.adjType = "visible";
16783                    }
16784                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16785                        procState = ActivityManager.PROCESS_STATE_TOP;
16786                    }
16787                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16788                    app.cached = false;
16789                    app.empty = false;
16790                    foregroundActivities = true;
16791                    break;
16792                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16793                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16794                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16795                        app.adjType = "pausing";
16796                    }
16797                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16798                        procState = ActivityManager.PROCESS_STATE_TOP;
16799                    }
16800                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16801                    app.cached = false;
16802                    app.empty = false;
16803                    foregroundActivities = true;
16804                } else if (r.state == ActivityState.STOPPING) {
16805                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16806                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16807                        app.adjType = "stopping";
16808                    }
16809                    // For the process state, we will at this point consider the
16810                    // process to be cached.  It will be cached either as an activity
16811                    // or empty depending on whether the activity is finishing.  We do
16812                    // this so that we can treat the process as cached for purposes of
16813                    // memory trimming (determing current memory level, trim command to
16814                    // send to process) since there can be an arbitrary number of stopping
16815                    // processes and they should soon all go into the cached state.
16816                    if (!r.finishing) {
16817                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16818                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16819                        }
16820                    }
16821                    app.cached = false;
16822                    app.empty = false;
16823                    foregroundActivities = true;
16824                } else {
16825                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16826                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16827                        app.adjType = "cch-act";
16828                    }
16829                }
16830            }
16831        }
16832
16833        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16834            if (app.foregroundServices) {
16835                // The user is aware of this app, so make it visible.
16836                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16837                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16838                app.cached = false;
16839                app.adjType = "fg-service";
16840                schedGroup = Process.THREAD_GROUP_DEFAULT;
16841            } else if (app.forcingToForeground != null) {
16842                // The user is aware of this app, so make it visible.
16843                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16844                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16845                app.cached = false;
16846                app.adjType = "force-fg";
16847                app.adjSource = app.forcingToForeground;
16848                schedGroup = Process.THREAD_GROUP_DEFAULT;
16849            }
16850        }
16851
16852        if (app == mHeavyWeightProcess) {
16853            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16854                // We don't want to kill the current heavy-weight process.
16855                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16856                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16857                app.cached = false;
16858                app.adjType = "heavy";
16859            }
16860            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16861                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16862            }
16863        }
16864
16865        if (app == mHomeProcess) {
16866            if (adj > ProcessList.HOME_APP_ADJ) {
16867                // This process is hosting what we currently consider to be the
16868                // home app, so we don't want to let it go into the background.
16869                adj = ProcessList.HOME_APP_ADJ;
16870                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16871                app.cached = false;
16872                app.adjType = "home";
16873            }
16874            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16875                procState = ActivityManager.PROCESS_STATE_HOME;
16876            }
16877        }
16878
16879        if (app == mPreviousProcess && app.activities.size() > 0) {
16880            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16881                // This was the previous process that showed UI to the user.
16882                // We want to try to keep it around more aggressively, to give
16883                // a good experience around switching between two apps.
16884                adj = ProcessList.PREVIOUS_APP_ADJ;
16885                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16886                app.cached = false;
16887                app.adjType = "previous";
16888            }
16889            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16890                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16891            }
16892        }
16893
16894        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16895                + " reason=" + app.adjType);
16896
16897        // By default, we use the computed adjustment.  It may be changed if
16898        // there are applications dependent on our services or providers, but
16899        // this gives us a baseline and makes sure we don't get into an
16900        // infinite recursion.
16901        app.adjSeq = mAdjSeq;
16902        app.curRawAdj = adj;
16903        app.hasStartedServices = false;
16904
16905        if (mBackupTarget != null && app == mBackupTarget.app) {
16906            // If possible we want to avoid killing apps while they're being backed up
16907            if (adj > ProcessList.BACKUP_APP_ADJ) {
16908                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16909                adj = ProcessList.BACKUP_APP_ADJ;
16910                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16911                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16912                }
16913                app.adjType = "backup";
16914                app.cached = false;
16915            }
16916            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16917                procState = ActivityManager.PROCESS_STATE_BACKUP;
16918            }
16919        }
16920
16921        boolean mayBeTop = false;
16922
16923        for (int is = app.services.size()-1;
16924                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16925                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16926                        || procState > ActivityManager.PROCESS_STATE_TOP);
16927                is--) {
16928            ServiceRecord s = app.services.valueAt(is);
16929            if (s.startRequested) {
16930                app.hasStartedServices = true;
16931                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16932                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16933                }
16934                if (app.hasShownUi && app != mHomeProcess) {
16935                    // If this process has shown some UI, let it immediately
16936                    // go to the LRU list because it may be pretty heavy with
16937                    // UI stuff.  We'll tag it with a label just to help
16938                    // debug and understand what is going on.
16939                    if (adj > ProcessList.SERVICE_ADJ) {
16940                        app.adjType = "cch-started-ui-services";
16941                    }
16942                } else {
16943                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16944                        // This service has seen some activity within
16945                        // recent memory, so we will keep its process ahead
16946                        // of the background processes.
16947                        if (adj > ProcessList.SERVICE_ADJ) {
16948                            adj = ProcessList.SERVICE_ADJ;
16949                            app.adjType = "started-services";
16950                            app.cached = false;
16951                        }
16952                    }
16953                    // If we have let the service slide into the background
16954                    // state, still have some text describing what it is doing
16955                    // even though the service no longer has an impact.
16956                    if (adj > ProcessList.SERVICE_ADJ) {
16957                        app.adjType = "cch-started-services";
16958                    }
16959                }
16960            }
16961            for (int conni = s.connections.size()-1;
16962                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16963                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16964                            || procState > ActivityManager.PROCESS_STATE_TOP);
16965                    conni--) {
16966                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16967                for (int i = 0;
16968                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16969                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16970                                || procState > ActivityManager.PROCESS_STATE_TOP);
16971                        i++) {
16972                    // XXX should compute this based on the max of
16973                    // all connected clients.
16974                    ConnectionRecord cr = clist.get(i);
16975                    if (cr.binding.client == app) {
16976                        // Binding to ourself is not interesting.
16977                        continue;
16978                    }
16979                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16980                        ProcessRecord client = cr.binding.client;
16981                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16982                                TOP_APP, doingAll, now);
16983                        int clientProcState = client.curProcState;
16984                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16985                            // If the other app is cached for any reason, for purposes here
16986                            // we are going to consider it empty.  The specific cached state
16987                            // doesn't propagate except under certain conditions.
16988                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16989                        }
16990                        String adjType = null;
16991                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16992                            // Not doing bind OOM management, so treat
16993                            // this guy more like a started service.
16994                            if (app.hasShownUi && app != mHomeProcess) {
16995                                // If this process has shown some UI, let it immediately
16996                                // go to the LRU list because it may be pretty heavy with
16997                                // UI stuff.  We'll tag it with a label just to help
16998                                // debug and understand what is going on.
16999                                if (adj > clientAdj) {
17000                                    adjType = "cch-bound-ui-services";
17001                                }
17002                                app.cached = false;
17003                                clientAdj = adj;
17004                                clientProcState = procState;
17005                            } else {
17006                                if (now >= (s.lastActivity
17007                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17008                                    // This service has not seen activity within
17009                                    // recent memory, so allow it to drop to the
17010                                    // LRU list if there is no other reason to keep
17011                                    // it around.  We'll also tag it with a label just
17012                                    // to help debug and undertand what is going on.
17013                                    if (adj > clientAdj) {
17014                                        adjType = "cch-bound-services";
17015                                    }
17016                                    clientAdj = adj;
17017                                }
17018                            }
17019                        }
17020                        if (adj > clientAdj) {
17021                            // If this process has recently shown UI, and
17022                            // the process that is binding to it is less
17023                            // important than being visible, then we don't
17024                            // care about the binding as much as we care
17025                            // about letting this process get into the LRU
17026                            // list to be killed and restarted if needed for
17027                            // memory.
17028                            if (app.hasShownUi && app != mHomeProcess
17029                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17030                                adjType = "cch-bound-ui-services";
17031                            } else {
17032                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17033                                        |Context.BIND_IMPORTANT)) != 0) {
17034                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17035                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17036                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17037                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17038                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17039                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17040                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17041                                    adj = clientAdj;
17042                                } else {
17043                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17044                                        adj = ProcessList.VISIBLE_APP_ADJ;
17045                                    }
17046                                }
17047                                if (!client.cached) {
17048                                    app.cached = false;
17049                                }
17050                                adjType = "service";
17051                            }
17052                        }
17053                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17054                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17055                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17056                            }
17057                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17058                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17059                                    // Special handling of clients who are in the top state.
17060                                    // We *may* want to consider this process to be in the
17061                                    // top state as well, but only if there is not another
17062                                    // reason for it to be running.  Being on the top is a
17063                                    // special state, meaning you are specifically running
17064                                    // for the current top app.  If the process is already
17065                                    // running in the background for some other reason, it
17066                                    // is more important to continue considering it to be
17067                                    // in the background state.
17068                                    mayBeTop = true;
17069                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17070                                } else {
17071                                    // Special handling for above-top states (persistent
17072                                    // processes).  These should not bring the current process
17073                                    // into the top state, since they are not on top.  Instead
17074                                    // give them the best state after that.
17075                                    clientProcState =
17076                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17077                                }
17078                            }
17079                        } else {
17080                            if (clientProcState <
17081                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17082                                clientProcState =
17083                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17084                            }
17085                        }
17086                        if (procState > clientProcState) {
17087                            procState = clientProcState;
17088                        }
17089                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17090                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17091                            app.pendingUiClean = true;
17092                        }
17093                        if (adjType != null) {
17094                            app.adjType = adjType;
17095                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17096                                    .REASON_SERVICE_IN_USE;
17097                            app.adjSource = cr.binding.client;
17098                            app.adjSourceProcState = clientProcState;
17099                            app.adjTarget = s.name;
17100                        }
17101                    }
17102                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17103                        app.treatLikeActivity = true;
17104                    }
17105                    final ActivityRecord a = cr.activity;
17106                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17107                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17108                                (a.visible || a.state == ActivityState.RESUMED
17109                                 || a.state == ActivityState.PAUSING)) {
17110                            adj = ProcessList.FOREGROUND_APP_ADJ;
17111                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17112                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17113                            }
17114                            app.cached = false;
17115                            app.adjType = "service";
17116                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17117                                    .REASON_SERVICE_IN_USE;
17118                            app.adjSource = a;
17119                            app.adjSourceProcState = procState;
17120                            app.adjTarget = s.name;
17121                        }
17122                    }
17123                }
17124            }
17125        }
17126
17127        for (int provi = app.pubProviders.size()-1;
17128                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17129                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17130                        || procState > ActivityManager.PROCESS_STATE_TOP);
17131                provi--) {
17132            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17133            for (int i = cpr.connections.size()-1;
17134                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17135                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17136                            || procState > ActivityManager.PROCESS_STATE_TOP);
17137                    i--) {
17138                ContentProviderConnection conn = cpr.connections.get(i);
17139                ProcessRecord client = conn.client;
17140                if (client == app) {
17141                    // Being our own client is not interesting.
17142                    continue;
17143                }
17144                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17145                int clientProcState = client.curProcState;
17146                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17147                    // If the other app is cached for any reason, for purposes here
17148                    // we are going to consider it empty.
17149                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17150                }
17151                if (adj > clientAdj) {
17152                    if (app.hasShownUi && app != mHomeProcess
17153                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17154                        app.adjType = "cch-ui-provider";
17155                    } else {
17156                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17157                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17158                        app.adjType = "provider";
17159                    }
17160                    app.cached &= client.cached;
17161                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17162                            .REASON_PROVIDER_IN_USE;
17163                    app.adjSource = client;
17164                    app.adjSourceProcState = clientProcState;
17165                    app.adjTarget = cpr.name;
17166                }
17167                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17168                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17169                        // Special handling of clients who are in the top state.
17170                        // We *may* want to consider this process to be in the
17171                        // top state as well, but only if there is not another
17172                        // reason for it to be running.  Being on the top is a
17173                        // special state, meaning you are specifically running
17174                        // for the current top app.  If the process is already
17175                        // running in the background for some other reason, it
17176                        // is more important to continue considering it to be
17177                        // in the background state.
17178                        mayBeTop = true;
17179                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17180                    } else {
17181                        // Special handling for above-top states (persistent
17182                        // processes).  These should not bring the current process
17183                        // into the top state, since they are not on top.  Instead
17184                        // give them the best state after that.
17185                        clientProcState =
17186                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17187                    }
17188                }
17189                if (procState > clientProcState) {
17190                    procState = clientProcState;
17191                }
17192                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17193                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17194                }
17195            }
17196            // If the provider has external (non-framework) process
17197            // dependencies, ensure that its adjustment is at least
17198            // FOREGROUND_APP_ADJ.
17199            if (cpr.hasExternalProcessHandles()) {
17200                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17201                    adj = ProcessList.FOREGROUND_APP_ADJ;
17202                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17203                    app.cached = false;
17204                    app.adjType = "provider";
17205                    app.adjTarget = cpr.name;
17206                }
17207                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17208                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17209                }
17210            }
17211        }
17212
17213        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17214            // A client of one of our services or providers is in the top state.  We
17215            // *may* want to be in the top state, but not if we are already running in
17216            // the background for some other reason.  For the decision here, we are going
17217            // to pick out a few specific states that we want to remain in when a client
17218            // is top (states that tend to be longer-term) and otherwise allow it to go
17219            // to the top state.
17220            switch (procState) {
17221                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17222                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17223                case ActivityManager.PROCESS_STATE_SERVICE:
17224                    // These all are longer-term states, so pull them up to the top
17225                    // of the background states, but not all the way to the top state.
17226                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17227                    break;
17228                default:
17229                    // Otherwise, top is a better choice, so take it.
17230                    procState = ActivityManager.PROCESS_STATE_TOP;
17231                    break;
17232            }
17233        }
17234
17235        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17236            if (app.hasClientActivities) {
17237                // This is a cached process, but with client activities.  Mark it so.
17238                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17239                app.adjType = "cch-client-act";
17240            } else if (app.treatLikeActivity) {
17241                // This is a cached process, but somebody wants us to treat it like it has
17242                // an activity, okay!
17243                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17244                app.adjType = "cch-as-act";
17245            }
17246        }
17247
17248        if (adj == ProcessList.SERVICE_ADJ) {
17249            if (doingAll) {
17250                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17251                mNewNumServiceProcs++;
17252                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17253                if (!app.serviceb) {
17254                    // This service isn't far enough down on the LRU list to
17255                    // normally be a B service, but if we are low on RAM and it
17256                    // is large we want to force it down since we would prefer to
17257                    // keep launcher over it.
17258                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17259                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17260                        app.serviceHighRam = true;
17261                        app.serviceb = true;
17262                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17263                    } else {
17264                        mNewNumAServiceProcs++;
17265                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17266                    }
17267                } else {
17268                    app.serviceHighRam = false;
17269                }
17270            }
17271            if (app.serviceb) {
17272                adj = ProcessList.SERVICE_B_ADJ;
17273            }
17274        }
17275
17276        app.curRawAdj = adj;
17277
17278        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17279        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17280        if (adj > app.maxAdj) {
17281            adj = app.maxAdj;
17282            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17283                schedGroup = Process.THREAD_GROUP_DEFAULT;
17284            }
17285        }
17286
17287        // Do final modification to adj.  Everything we do between here and applying
17288        // the final setAdj must be done in this function, because we will also use
17289        // it when computing the final cached adj later.  Note that we don't need to
17290        // worry about this for max adj above, since max adj will always be used to
17291        // keep it out of the cached vaues.
17292        app.curAdj = app.modifyRawOomAdj(adj);
17293        app.curSchedGroup = schedGroup;
17294        app.curProcState = procState;
17295        app.foregroundActivities = foregroundActivities;
17296
17297        return app.curRawAdj;
17298    }
17299
17300    /**
17301     * Schedule PSS collection of a process.
17302     */
17303    void requestPssLocked(ProcessRecord proc, int procState) {
17304        if (mPendingPssProcesses.contains(proc)) {
17305            return;
17306        }
17307        if (mPendingPssProcesses.size() == 0) {
17308            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17309        }
17310        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17311        proc.pssProcState = procState;
17312        mPendingPssProcesses.add(proc);
17313    }
17314
17315    /**
17316     * Schedule PSS collection of all processes.
17317     */
17318    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17319        if (!always) {
17320            if (now < (mLastFullPssTime +
17321                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17322                return;
17323            }
17324        }
17325        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17326        mLastFullPssTime = now;
17327        mFullPssPending = true;
17328        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17329        mPendingPssProcesses.clear();
17330        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17331            ProcessRecord app = mLruProcesses.get(i);
17332            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17333                app.pssProcState = app.setProcState;
17334                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17335                        isSleeping(), now);
17336                mPendingPssProcesses.add(app);
17337            }
17338        }
17339        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17340    }
17341
17342    /**
17343     * Ask a given process to GC right now.
17344     */
17345    final void performAppGcLocked(ProcessRecord app) {
17346        try {
17347            app.lastRequestedGc = SystemClock.uptimeMillis();
17348            if (app.thread != null) {
17349                if (app.reportLowMemory) {
17350                    app.reportLowMemory = false;
17351                    app.thread.scheduleLowMemory();
17352                } else {
17353                    app.thread.processInBackground();
17354                }
17355            }
17356        } catch (Exception e) {
17357            // whatever.
17358        }
17359    }
17360
17361    /**
17362     * Returns true if things are idle enough to perform GCs.
17363     */
17364    private final boolean canGcNowLocked() {
17365        boolean processingBroadcasts = false;
17366        for (BroadcastQueue q : mBroadcastQueues) {
17367            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17368                processingBroadcasts = true;
17369            }
17370        }
17371        return !processingBroadcasts
17372                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17373    }
17374
17375    /**
17376     * Perform GCs on all processes that are waiting for it, but only
17377     * if things are idle.
17378     */
17379    final void performAppGcsLocked() {
17380        final int N = mProcessesToGc.size();
17381        if (N <= 0) {
17382            return;
17383        }
17384        if (canGcNowLocked()) {
17385            while (mProcessesToGc.size() > 0) {
17386                ProcessRecord proc = mProcessesToGc.remove(0);
17387                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17388                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17389                            <= SystemClock.uptimeMillis()) {
17390                        // To avoid spamming the system, we will GC processes one
17391                        // at a time, waiting a few seconds between each.
17392                        performAppGcLocked(proc);
17393                        scheduleAppGcsLocked();
17394                        return;
17395                    } else {
17396                        // It hasn't been long enough since we last GCed this
17397                        // process...  put it in the list to wait for its time.
17398                        addProcessToGcListLocked(proc);
17399                        break;
17400                    }
17401                }
17402            }
17403
17404            scheduleAppGcsLocked();
17405        }
17406    }
17407
17408    /**
17409     * If all looks good, perform GCs on all processes waiting for them.
17410     */
17411    final void performAppGcsIfAppropriateLocked() {
17412        if (canGcNowLocked()) {
17413            performAppGcsLocked();
17414            return;
17415        }
17416        // Still not idle, wait some more.
17417        scheduleAppGcsLocked();
17418    }
17419
17420    /**
17421     * Schedule the execution of all pending app GCs.
17422     */
17423    final void scheduleAppGcsLocked() {
17424        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17425
17426        if (mProcessesToGc.size() > 0) {
17427            // Schedule a GC for the time to the next process.
17428            ProcessRecord proc = mProcessesToGc.get(0);
17429            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17430
17431            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17432            long now = SystemClock.uptimeMillis();
17433            if (when < (now+GC_TIMEOUT)) {
17434                when = now + GC_TIMEOUT;
17435            }
17436            mHandler.sendMessageAtTime(msg, when);
17437        }
17438    }
17439
17440    /**
17441     * Add a process to the array of processes waiting to be GCed.  Keeps the
17442     * list in sorted order by the last GC time.  The process can't already be
17443     * on the list.
17444     */
17445    final void addProcessToGcListLocked(ProcessRecord proc) {
17446        boolean added = false;
17447        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17448            if (mProcessesToGc.get(i).lastRequestedGc <
17449                    proc.lastRequestedGc) {
17450                added = true;
17451                mProcessesToGc.add(i+1, proc);
17452                break;
17453            }
17454        }
17455        if (!added) {
17456            mProcessesToGc.add(0, proc);
17457        }
17458    }
17459
17460    /**
17461     * Set up to ask a process to GC itself.  This will either do it
17462     * immediately, or put it on the list of processes to gc the next
17463     * time things are idle.
17464     */
17465    final void scheduleAppGcLocked(ProcessRecord app) {
17466        long now = SystemClock.uptimeMillis();
17467        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17468            return;
17469        }
17470        if (!mProcessesToGc.contains(app)) {
17471            addProcessToGcListLocked(app);
17472            scheduleAppGcsLocked();
17473        }
17474    }
17475
17476    final void checkExcessivePowerUsageLocked(boolean doKills) {
17477        updateCpuStatsNow();
17478
17479        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17480        boolean doWakeKills = doKills;
17481        boolean doCpuKills = doKills;
17482        if (mLastPowerCheckRealtime == 0) {
17483            doWakeKills = false;
17484        }
17485        if (mLastPowerCheckUptime == 0) {
17486            doCpuKills = false;
17487        }
17488        if (stats.isScreenOn()) {
17489            doWakeKills = false;
17490        }
17491        final long curRealtime = SystemClock.elapsedRealtime();
17492        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17493        final long curUptime = SystemClock.uptimeMillis();
17494        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17495        mLastPowerCheckRealtime = curRealtime;
17496        mLastPowerCheckUptime = curUptime;
17497        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17498            doWakeKills = false;
17499        }
17500        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17501            doCpuKills = false;
17502        }
17503        int i = mLruProcesses.size();
17504        while (i > 0) {
17505            i--;
17506            ProcessRecord app = mLruProcesses.get(i);
17507            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17508                long wtime;
17509                synchronized (stats) {
17510                    wtime = stats.getProcessWakeTime(app.info.uid,
17511                            app.pid, curRealtime);
17512                }
17513                long wtimeUsed = wtime - app.lastWakeTime;
17514                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17515                if (DEBUG_POWER) {
17516                    StringBuilder sb = new StringBuilder(128);
17517                    sb.append("Wake for ");
17518                    app.toShortString(sb);
17519                    sb.append(": over ");
17520                    TimeUtils.formatDuration(realtimeSince, sb);
17521                    sb.append(" used ");
17522                    TimeUtils.formatDuration(wtimeUsed, sb);
17523                    sb.append(" (");
17524                    sb.append((wtimeUsed*100)/realtimeSince);
17525                    sb.append("%)");
17526                    Slog.i(TAG, sb.toString());
17527                    sb.setLength(0);
17528                    sb.append("CPU for ");
17529                    app.toShortString(sb);
17530                    sb.append(": over ");
17531                    TimeUtils.formatDuration(uptimeSince, sb);
17532                    sb.append(" used ");
17533                    TimeUtils.formatDuration(cputimeUsed, sb);
17534                    sb.append(" (");
17535                    sb.append((cputimeUsed*100)/uptimeSince);
17536                    sb.append("%)");
17537                    Slog.i(TAG, sb.toString());
17538                }
17539                // If a process has held a wake lock for more
17540                // than 50% of the time during this period,
17541                // that sounds bad.  Kill!
17542                if (doWakeKills && realtimeSince > 0
17543                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17544                    synchronized (stats) {
17545                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17546                                realtimeSince, wtimeUsed);
17547                    }
17548                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17549                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17550                } else if (doCpuKills && uptimeSince > 0
17551                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17552                    synchronized (stats) {
17553                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17554                                uptimeSince, cputimeUsed);
17555                    }
17556                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17557                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17558                } else {
17559                    app.lastWakeTime = wtime;
17560                    app.lastCpuTime = app.curCpuTime;
17561                }
17562            }
17563        }
17564    }
17565
17566    private final boolean applyOomAdjLocked(ProcessRecord app,
17567            ProcessRecord TOP_APP, boolean doingAll, long now) {
17568        boolean success = true;
17569
17570        if (app.curRawAdj != app.setRawAdj) {
17571            app.setRawAdj = app.curRawAdj;
17572        }
17573
17574        int changes = 0;
17575
17576        if (app.curAdj != app.setAdj) {
17577            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17578            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17579                TAG, "Set " + app.pid + " " + app.processName +
17580                " adj " + app.curAdj + ": " + app.adjType);
17581            app.setAdj = app.curAdj;
17582        }
17583
17584        if (app.setSchedGroup != app.curSchedGroup) {
17585            app.setSchedGroup = app.curSchedGroup;
17586            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17587                    "Setting process group of " + app.processName
17588                    + " to " + app.curSchedGroup);
17589            if (app.waitingToKill != null &&
17590                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17591                app.kill(app.waitingToKill, true);
17592                success = false;
17593            } else {
17594                if (true) {
17595                    long oldId = Binder.clearCallingIdentity();
17596                    try {
17597                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17598                    } catch (Exception e) {
17599                        Slog.w(TAG, "Failed setting process group of " + app.pid
17600                                + " to " + app.curSchedGroup);
17601                        e.printStackTrace();
17602                    } finally {
17603                        Binder.restoreCallingIdentity(oldId);
17604                    }
17605                } else {
17606                    if (app.thread != null) {
17607                        try {
17608                            app.thread.setSchedulingGroup(app.curSchedGroup);
17609                        } catch (RemoteException e) {
17610                        }
17611                    }
17612                }
17613                Process.setSwappiness(app.pid,
17614                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17615            }
17616        }
17617        if (app.repForegroundActivities != app.foregroundActivities) {
17618            app.repForegroundActivities = app.foregroundActivities;
17619            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17620        }
17621        if (app.repProcState != app.curProcState) {
17622            app.repProcState = app.curProcState;
17623            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17624            if (app.thread != null) {
17625                try {
17626                    if (false) {
17627                        //RuntimeException h = new RuntimeException("here");
17628                        Slog.i(TAG, "Sending new process state " + app.repProcState
17629                                + " to " + app /*, h*/);
17630                    }
17631                    app.thread.setProcessState(app.repProcState);
17632                } catch (RemoteException e) {
17633                }
17634            }
17635        }
17636        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17637                app.setProcState)) {
17638            app.lastStateTime = now;
17639            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17640                    isSleeping(), now);
17641            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17642                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17643                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17644                    + (app.nextPssTime-now) + ": " + app);
17645        } else {
17646            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17647                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17648                requestPssLocked(app, app.setProcState);
17649                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17650                        isSleeping(), now);
17651            } else if (false && DEBUG_PSS) {
17652                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17653            }
17654        }
17655        if (app.setProcState != app.curProcState) {
17656            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17657                    "Proc state change of " + app.processName
17658                    + " to " + app.curProcState);
17659            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17660            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17661            if (setImportant && !curImportant) {
17662                // This app is no longer something we consider important enough to allow to
17663                // use arbitrary amounts of battery power.  Note
17664                // its current wake lock time to later know to kill it if
17665                // it is not behaving well.
17666                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17667                synchronized (stats) {
17668                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17669                            app.pid, SystemClock.elapsedRealtime());
17670                }
17671                app.lastCpuTime = app.curCpuTime;
17672
17673            }
17674            app.setProcState = app.curProcState;
17675            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17676                app.notCachedSinceIdle = false;
17677            }
17678            if (!doingAll) {
17679                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17680            } else {
17681                app.procStateChanged = true;
17682            }
17683        }
17684
17685        if (changes != 0) {
17686            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17687            int i = mPendingProcessChanges.size()-1;
17688            ProcessChangeItem item = null;
17689            while (i >= 0) {
17690                item = mPendingProcessChanges.get(i);
17691                if (item.pid == app.pid) {
17692                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17693                    break;
17694                }
17695                i--;
17696            }
17697            if (i < 0) {
17698                // No existing item in pending changes; need a new one.
17699                final int NA = mAvailProcessChanges.size();
17700                if (NA > 0) {
17701                    item = mAvailProcessChanges.remove(NA-1);
17702                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17703                } else {
17704                    item = new ProcessChangeItem();
17705                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17706                }
17707                item.changes = 0;
17708                item.pid = app.pid;
17709                item.uid = app.info.uid;
17710                if (mPendingProcessChanges.size() == 0) {
17711                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17712                            "*** Enqueueing dispatch processes changed!");
17713                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17714                }
17715                mPendingProcessChanges.add(item);
17716            }
17717            item.changes |= changes;
17718            item.processState = app.repProcState;
17719            item.foregroundActivities = app.repForegroundActivities;
17720            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17721                    + Integer.toHexString(System.identityHashCode(item))
17722                    + " " + app.toShortString() + ": changes=" + item.changes
17723                    + " procState=" + item.processState
17724                    + " foreground=" + item.foregroundActivities
17725                    + " type=" + app.adjType + " source=" + app.adjSource
17726                    + " target=" + app.adjTarget);
17727        }
17728
17729        return success;
17730    }
17731
17732    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17733        if (proc.thread != null) {
17734            if (proc.baseProcessTracker != null) {
17735                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17736            }
17737            if (proc.repProcState >= 0) {
17738                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17739                        proc.repProcState);
17740            }
17741        }
17742    }
17743
17744    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17745            ProcessRecord TOP_APP, boolean doingAll, long now) {
17746        if (app.thread == null) {
17747            return false;
17748        }
17749
17750        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17751
17752        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17753    }
17754
17755    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17756            boolean oomAdj) {
17757        if (isForeground != proc.foregroundServices) {
17758            proc.foregroundServices = isForeground;
17759            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17760                    proc.info.uid);
17761            if (isForeground) {
17762                if (curProcs == null) {
17763                    curProcs = new ArrayList<ProcessRecord>();
17764                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17765                }
17766                if (!curProcs.contains(proc)) {
17767                    curProcs.add(proc);
17768                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17769                            proc.info.packageName, proc.info.uid);
17770                }
17771            } else {
17772                if (curProcs != null) {
17773                    if (curProcs.remove(proc)) {
17774                        mBatteryStatsService.noteEvent(
17775                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17776                                proc.info.packageName, proc.info.uid);
17777                        if (curProcs.size() <= 0) {
17778                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17779                        }
17780                    }
17781                }
17782            }
17783            if (oomAdj) {
17784                updateOomAdjLocked();
17785            }
17786        }
17787    }
17788
17789    private final ActivityRecord resumedAppLocked() {
17790        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17791        String pkg;
17792        int uid;
17793        if (act != null) {
17794            pkg = act.packageName;
17795            uid = act.info.applicationInfo.uid;
17796        } else {
17797            pkg = null;
17798            uid = -1;
17799        }
17800        // Has the UID or resumed package name changed?
17801        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17802                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17803            if (mCurResumedPackage != null) {
17804                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17805                        mCurResumedPackage, mCurResumedUid);
17806            }
17807            mCurResumedPackage = pkg;
17808            mCurResumedUid = uid;
17809            if (mCurResumedPackage != null) {
17810                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17811                        mCurResumedPackage, mCurResumedUid);
17812            }
17813        }
17814        return act;
17815    }
17816
17817    final boolean updateOomAdjLocked(ProcessRecord app) {
17818        final ActivityRecord TOP_ACT = resumedAppLocked();
17819        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17820        final boolean wasCached = app.cached;
17821
17822        mAdjSeq++;
17823
17824        // This is the desired cached adjusment we want to tell it to use.
17825        // If our app is currently cached, we know it, and that is it.  Otherwise,
17826        // we don't know it yet, and it needs to now be cached we will then
17827        // need to do a complete oom adj.
17828        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17829                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17830        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17831                SystemClock.uptimeMillis());
17832        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17833            // Changed to/from cached state, so apps after it in the LRU
17834            // list may also be changed.
17835            updateOomAdjLocked();
17836        }
17837        return success;
17838    }
17839
17840    final void updateOomAdjLocked() {
17841        final ActivityRecord TOP_ACT = resumedAppLocked();
17842        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17843        final long now = SystemClock.uptimeMillis();
17844        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17845        final int N = mLruProcesses.size();
17846
17847        if (false) {
17848            RuntimeException e = new RuntimeException();
17849            e.fillInStackTrace();
17850            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17851        }
17852
17853        mAdjSeq++;
17854        mNewNumServiceProcs = 0;
17855        mNewNumAServiceProcs = 0;
17856
17857        final int emptyProcessLimit;
17858        final int cachedProcessLimit;
17859        if (mProcessLimit <= 0) {
17860            emptyProcessLimit = cachedProcessLimit = 0;
17861        } else if (mProcessLimit == 1) {
17862            emptyProcessLimit = 1;
17863            cachedProcessLimit = 0;
17864        } else {
17865            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17866            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17867        }
17868
17869        // Let's determine how many processes we have running vs.
17870        // how many slots we have for background processes; we may want
17871        // to put multiple processes in a slot of there are enough of
17872        // them.
17873        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17874                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17875        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17876        if (numEmptyProcs > cachedProcessLimit) {
17877            // If there are more empty processes than our limit on cached
17878            // processes, then use the cached process limit for the factor.
17879            // This ensures that the really old empty processes get pushed
17880            // down to the bottom, so if we are running low on memory we will
17881            // have a better chance at keeping around more cached processes
17882            // instead of a gazillion empty processes.
17883            numEmptyProcs = cachedProcessLimit;
17884        }
17885        int emptyFactor = numEmptyProcs/numSlots;
17886        if (emptyFactor < 1) emptyFactor = 1;
17887        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17888        if (cachedFactor < 1) cachedFactor = 1;
17889        int stepCached = 0;
17890        int stepEmpty = 0;
17891        int numCached = 0;
17892        int numEmpty = 0;
17893        int numTrimming = 0;
17894
17895        mNumNonCachedProcs = 0;
17896        mNumCachedHiddenProcs = 0;
17897
17898        // First update the OOM adjustment for each of the
17899        // application processes based on their current state.
17900        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17901        int nextCachedAdj = curCachedAdj+1;
17902        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17903        int nextEmptyAdj = curEmptyAdj+2;
17904        for (int i=N-1; i>=0; i--) {
17905            ProcessRecord app = mLruProcesses.get(i);
17906            if (!app.killedByAm && app.thread != null) {
17907                app.procStateChanged = false;
17908                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17909
17910                // If we haven't yet assigned the final cached adj
17911                // to the process, do that now.
17912                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17913                    switch (app.curProcState) {
17914                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17915                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17916                            // This process is a cached process holding activities...
17917                            // assign it the next cached value for that type, and then
17918                            // step that cached level.
17919                            app.curRawAdj = curCachedAdj;
17920                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17921                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17922                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17923                                    + ")");
17924                            if (curCachedAdj != nextCachedAdj) {
17925                                stepCached++;
17926                                if (stepCached >= cachedFactor) {
17927                                    stepCached = 0;
17928                                    curCachedAdj = nextCachedAdj;
17929                                    nextCachedAdj += 2;
17930                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17931                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17932                                    }
17933                                }
17934                            }
17935                            break;
17936                        default:
17937                            // For everything else, assign next empty cached process
17938                            // level and bump that up.  Note that this means that
17939                            // long-running services that have dropped down to the
17940                            // cached level will be treated as empty (since their process
17941                            // state is still as a service), which is what we want.
17942                            app.curRawAdj = curEmptyAdj;
17943                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17944                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17945                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17946                                    + ")");
17947                            if (curEmptyAdj != nextEmptyAdj) {
17948                                stepEmpty++;
17949                                if (stepEmpty >= emptyFactor) {
17950                                    stepEmpty = 0;
17951                                    curEmptyAdj = nextEmptyAdj;
17952                                    nextEmptyAdj += 2;
17953                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17954                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17955                                    }
17956                                }
17957                            }
17958                            break;
17959                    }
17960                }
17961
17962                applyOomAdjLocked(app, TOP_APP, true, now);
17963
17964                // Count the number of process types.
17965                switch (app.curProcState) {
17966                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17967                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17968                        mNumCachedHiddenProcs++;
17969                        numCached++;
17970                        if (numCached > cachedProcessLimit) {
17971                            app.kill("cached #" + numCached, true);
17972                        }
17973                        break;
17974                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17975                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17976                                && app.lastActivityTime < oldTime) {
17977                            app.kill("empty for "
17978                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17979                                    / 1000) + "s", true);
17980                        } else {
17981                            numEmpty++;
17982                            if (numEmpty > emptyProcessLimit) {
17983                                app.kill("empty #" + numEmpty, true);
17984                            }
17985                        }
17986                        break;
17987                    default:
17988                        mNumNonCachedProcs++;
17989                        break;
17990                }
17991
17992                if (app.isolated && app.services.size() <= 0) {
17993                    // If this is an isolated process, and there are no
17994                    // services running in it, then the process is no longer
17995                    // needed.  We agressively kill these because we can by
17996                    // definition not re-use the same process again, and it is
17997                    // good to avoid having whatever code was running in them
17998                    // left sitting around after no longer needed.
17999                    app.kill("isolated not needed", true);
18000                }
18001
18002                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18003                        && !app.killedByAm) {
18004                    numTrimming++;
18005                }
18006            }
18007        }
18008
18009        mNumServiceProcs = mNewNumServiceProcs;
18010
18011        // Now determine the memory trimming level of background processes.
18012        // Unfortunately we need to start at the back of the list to do this
18013        // properly.  We only do this if the number of background apps we
18014        // are managing to keep around is less than half the maximum we desire;
18015        // if we are keeping a good number around, we'll let them use whatever
18016        // memory they want.
18017        final int numCachedAndEmpty = numCached + numEmpty;
18018        int memFactor;
18019        if (numCached <= ProcessList.TRIM_CACHED_APPS
18020                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18021            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18022                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18023            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18024                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18025            } else {
18026                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18027            }
18028        } else {
18029            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18030        }
18031        // We always allow the memory level to go up (better).  We only allow it to go
18032        // down if we are in a state where that is allowed, *and* the total number of processes
18033        // has gone down since last time.
18034        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18035                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18036                + " last=" + mLastNumProcesses);
18037        if (memFactor > mLastMemoryLevel) {
18038            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18039                memFactor = mLastMemoryLevel;
18040                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18041            }
18042        }
18043        mLastMemoryLevel = memFactor;
18044        mLastNumProcesses = mLruProcesses.size();
18045        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18046        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18047        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18048            if (mLowRamStartTime == 0) {
18049                mLowRamStartTime = now;
18050            }
18051            int step = 0;
18052            int fgTrimLevel;
18053            switch (memFactor) {
18054                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18055                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18056                    break;
18057                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18058                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18059                    break;
18060                default:
18061                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18062                    break;
18063            }
18064            int factor = numTrimming/3;
18065            int minFactor = 2;
18066            if (mHomeProcess != null) minFactor++;
18067            if (mPreviousProcess != null) minFactor++;
18068            if (factor < minFactor) factor = minFactor;
18069            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18070            for (int i=N-1; i>=0; i--) {
18071                ProcessRecord app = mLruProcesses.get(i);
18072                if (allChanged || app.procStateChanged) {
18073                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18074                    app.procStateChanged = false;
18075                }
18076                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18077                        && !app.killedByAm) {
18078                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18079                        try {
18080                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18081                                    "Trimming memory of " + app.processName
18082                                    + " to " + curLevel);
18083                            app.thread.scheduleTrimMemory(curLevel);
18084                        } catch (RemoteException e) {
18085                        }
18086                        if (false) {
18087                            // For now we won't do this; our memory trimming seems
18088                            // to be good enough at this point that destroying
18089                            // activities causes more harm than good.
18090                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18091                                    && app != mHomeProcess && app != mPreviousProcess) {
18092                                // Need to do this on its own message because the stack may not
18093                                // be in a consistent state at this point.
18094                                // For these apps we will also finish their activities
18095                                // to help them free memory.
18096                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18097                            }
18098                        }
18099                    }
18100                    app.trimMemoryLevel = curLevel;
18101                    step++;
18102                    if (step >= factor) {
18103                        step = 0;
18104                        switch (curLevel) {
18105                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18106                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18107                                break;
18108                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18109                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18110                                break;
18111                        }
18112                    }
18113                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18114                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18115                            && app.thread != null) {
18116                        try {
18117                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18118                                    "Trimming memory of heavy-weight " + app.processName
18119                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18120                            app.thread.scheduleTrimMemory(
18121                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18122                        } catch (RemoteException e) {
18123                        }
18124                    }
18125                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18126                } else {
18127                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18128                            || app.systemNoUi) && app.pendingUiClean) {
18129                        // If this application is now in the background and it
18130                        // had done UI, then give it the special trim level to
18131                        // have it free UI resources.
18132                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18133                        if (app.trimMemoryLevel < level && app.thread != null) {
18134                            try {
18135                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18136                                        "Trimming memory of bg-ui " + app.processName
18137                                        + " to " + level);
18138                                app.thread.scheduleTrimMemory(level);
18139                            } catch (RemoteException e) {
18140                            }
18141                        }
18142                        app.pendingUiClean = false;
18143                    }
18144                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18145                        try {
18146                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18147                                    "Trimming memory of fg " + app.processName
18148                                    + " to " + fgTrimLevel);
18149                            app.thread.scheduleTrimMemory(fgTrimLevel);
18150                        } catch (RemoteException e) {
18151                        }
18152                    }
18153                    app.trimMemoryLevel = fgTrimLevel;
18154                }
18155            }
18156        } else {
18157            if (mLowRamStartTime != 0) {
18158                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18159                mLowRamStartTime = 0;
18160            }
18161            for (int i=N-1; i>=0; i--) {
18162                ProcessRecord app = mLruProcesses.get(i);
18163                if (allChanged || app.procStateChanged) {
18164                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18165                    app.procStateChanged = false;
18166                }
18167                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18168                        || app.systemNoUi) && app.pendingUiClean) {
18169                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18170                            && app.thread != null) {
18171                        try {
18172                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18173                                    "Trimming memory of ui hidden " + app.processName
18174                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18175                            app.thread.scheduleTrimMemory(
18176                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18177                        } catch (RemoteException e) {
18178                        }
18179                    }
18180                    app.pendingUiClean = false;
18181                }
18182                app.trimMemoryLevel = 0;
18183            }
18184        }
18185
18186        if (mAlwaysFinishActivities) {
18187            // Need to do this on its own message because the stack may not
18188            // be in a consistent state at this point.
18189            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18190        }
18191
18192        if (allChanged) {
18193            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18194        }
18195
18196        if (mProcessStats.shouldWriteNowLocked(now)) {
18197            mHandler.post(new Runnable() {
18198                @Override public void run() {
18199                    synchronized (ActivityManagerService.this) {
18200                        mProcessStats.writeStateAsyncLocked();
18201                    }
18202                }
18203            });
18204        }
18205
18206        if (DEBUG_OOM_ADJ) {
18207            if (false) {
18208                RuntimeException here = new RuntimeException("here");
18209                here.fillInStackTrace();
18210                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18211            } else {
18212                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18213            }
18214        }
18215    }
18216
18217    final void trimApplications() {
18218        synchronized (this) {
18219            int i;
18220
18221            // First remove any unused application processes whose package
18222            // has been removed.
18223            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18224                final ProcessRecord app = mRemovedProcesses.get(i);
18225                if (app.activities.size() == 0
18226                        && app.curReceiver == null && app.services.size() == 0) {
18227                    Slog.i(
18228                        TAG, "Exiting empty application process "
18229                        + app.processName + " ("
18230                        + (app.thread != null ? app.thread.asBinder() : null)
18231                        + ")\n");
18232                    if (app.pid > 0 && app.pid != MY_PID) {
18233                        app.kill("empty", false);
18234                    } else {
18235                        try {
18236                            app.thread.scheduleExit();
18237                        } catch (Exception e) {
18238                            // Ignore exceptions.
18239                        }
18240                    }
18241                    cleanUpApplicationRecordLocked(app, false, true, -1);
18242                    mRemovedProcesses.remove(i);
18243
18244                    if (app.persistent) {
18245                        addAppLocked(app.info, false, null /* ABI override */);
18246                    }
18247                }
18248            }
18249
18250            // Now update the oom adj for all processes.
18251            updateOomAdjLocked();
18252        }
18253    }
18254
18255    /** This method sends the specified signal to each of the persistent apps */
18256    public void signalPersistentProcesses(int sig) throws RemoteException {
18257        if (sig != Process.SIGNAL_USR1) {
18258            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18259        }
18260
18261        synchronized (this) {
18262            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18263                    != PackageManager.PERMISSION_GRANTED) {
18264                throw new SecurityException("Requires permission "
18265                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18266            }
18267
18268            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18269                ProcessRecord r = mLruProcesses.get(i);
18270                if (r.thread != null && r.persistent) {
18271                    Process.sendSignal(r.pid, sig);
18272                }
18273            }
18274        }
18275    }
18276
18277    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18278        if (proc == null || proc == mProfileProc) {
18279            proc = mProfileProc;
18280            profileType = mProfileType;
18281            clearProfilerLocked();
18282        }
18283        if (proc == null) {
18284            return;
18285        }
18286        try {
18287            proc.thread.profilerControl(false, null, profileType);
18288        } catch (RemoteException e) {
18289            throw new IllegalStateException("Process disappeared");
18290        }
18291    }
18292
18293    private void clearProfilerLocked() {
18294        if (mProfileFd != null) {
18295            try {
18296                mProfileFd.close();
18297            } catch (IOException e) {
18298            }
18299        }
18300        mProfileApp = null;
18301        mProfileProc = null;
18302        mProfileFile = null;
18303        mProfileType = 0;
18304        mAutoStopProfiler = false;
18305        mSamplingInterval = 0;
18306    }
18307
18308    public boolean profileControl(String process, int userId, boolean start,
18309            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18310
18311        try {
18312            synchronized (this) {
18313                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18314                // its own permission.
18315                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18316                        != PackageManager.PERMISSION_GRANTED) {
18317                    throw new SecurityException("Requires permission "
18318                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18319                }
18320
18321                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18322                    throw new IllegalArgumentException("null profile info or fd");
18323                }
18324
18325                ProcessRecord proc = null;
18326                if (process != null) {
18327                    proc = findProcessLocked(process, userId, "profileControl");
18328                }
18329
18330                if (start && (proc == null || proc.thread == null)) {
18331                    throw new IllegalArgumentException("Unknown process: " + process);
18332                }
18333
18334                if (start) {
18335                    stopProfilerLocked(null, 0);
18336                    setProfileApp(proc.info, proc.processName, profilerInfo);
18337                    mProfileProc = proc;
18338                    mProfileType = profileType;
18339                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18340                    try {
18341                        fd = fd.dup();
18342                    } catch (IOException e) {
18343                        fd = null;
18344                    }
18345                    profilerInfo.profileFd = fd;
18346                    proc.thread.profilerControl(start, profilerInfo, profileType);
18347                    fd = null;
18348                    mProfileFd = null;
18349                } else {
18350                    stopProfilerLocked(proc, profileType);
18351                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18352                        try {
18353                            profilerInfo.profileFd.close();
18354                        } catch (IOException e) {
18355                        }
18356                    }
18357                }
18358
18359                return true;
18360            }
18361        } catch (RemoteException e) {
18362            throw new IllegalStateException("Process disappeared");
18363        } finally {
18364            if (profilerInfo != null && profilerInfo.profileFd != null) {
18365                try {
18366                    profilerInfo.profileFd.close();
18367                } catch (IOException e) {
18368                }
18369            }
18370        }
18371    }
18372
18373    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18374        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18375                userId, true, ALLOW_FULL_ONLY, callName, null);
18376        ProcessRecord proc = null;
18377        try {
18378            int pid = Integer.parseInt(process);
18379            synchronized (mPidsSelfLocked) {
18380                proc = mPidsSelfLocked.get(pid);
18381            }
18382        } catch (NumberFormatException e) {
18383        }
18384
18385        if (proc == null) {
18386            ArrayMap<String, SparseArray<ProcessRecord>> all
18387                    = mProcessNames.getMap();
18388            SparseArray<ProcessRecord> procs = all.get(process);
18389            if (procs != null && procs.size() > 0) {
18390                proc = procs.valueAt(0);
18391                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18392                    for (int i=1; i<procs.size(); i++) {
18393                        ProcessRecord thisProc = procs.valueAt(i);
18394                        if (thisProc.userId == userId) {
18395                            proc = thisProc;
18396                            break;
18397                        }
18398                    }
18399                }
18400            }
18401        }
18402
18403        return proc;
18404    }
18405
18406    public boolean dumpHeap(String process, int userId, boolean managed,
18407            String path, ParcelFileDescriptor fd) throws RemoteException {
18408
18409        try {
18410            synchronized (this) {
18411                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18412                // its own permission (same as profileControl).
18413                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18414                        != PackageManager.PERMISSION_GRANTED) {
18415                    throw new SecurityException("Requires permission "
18416                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18417                }
18418
18419                if (fd == null) {
18420                    throw new IllegalArgumentException("null fd");
18421                }
18422
18423                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18424                if (proc == null || proc.thread == null) {
18425                    throw new IllegalArgumentException("Unknown process: " + process);
18426                }
18427
18428                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18429                if (!isDebuggable) {
18430                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18431                        throw new SecurityException("Process not debuggable: " + proc);
18432                    }
18433                }
18434
18435                proc.thread.dumpHeap(managed, path, fd);
18436                fd = null;
18437                return true;
18438            }
18439        } catch (RemoteException e) {
18440            throw new IllegalStateException("Process disappeared");
18441        } finally {
18442            if (fd != null) {
18443                try {
18444                    fd.close();
18445                } catch (IOException e) {
18446                }
18447            }
18448        }
18449    }
18450
18451    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18452    public void monitor() {
18453        synchronized (this) { }
18454    }
18455
18456    void onCoreSettingsChange(Bundle settings) {
18457        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18458            ProcessRecord processRecord = mLruProcesses.get(i);
18459            try {
18460                if (processRecord.thread != null) {
18461                    processRecord.thread.setCoreSettings(settings);
18462                }
18463            } catch (RemoteException re) {
18464                /* ignore */
18465            }
18466        }
18467    }
18468
18469    // Multi-user methods
18470
18471    /**
18472     * Start user, if its not already running, but don't bring it to foreground.
18473     */
18474    @Override
18475    public boolean startUserInBackground(final int userId) {
18476        return startUser(userId, /* foreground */ false);
18477    }
18478
18479    /**
18480     * Start user, if its not already running, and bring it to foreground.
18481     */
18482    boolean startUserInForeground(final int userId, Dialog dlg) {
18483        boolean result = startUser(userId, /* foreground */ true);
18484        dlg.dismiss();
18485        return result;
18486    }
18487
18488    /**
18489     * Refreshes the list of users related to the current user when either a
18490     * user switch happens or when a new related user is started in the
18491     * background.
18492     */
18493    private void updateCurrentProfileIdsLocked() {
18494        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18495                mCurrentUserId, false /* enabledOnly */);
18496        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18497        for (int i = 0; i < currentProfileIds.length; i++) {
18498            currentProfileIds[i] = profiles.get(i).id;
18499        }
18500        mCurrentProfileIds = currentProfileIds;
18501
18502        synchronized (mUserProfileGroupIdsSelfLocked) {
18503            mUserProfileGroupIdsSelfLocked.clear();
18504            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18505            for (int i = 0; i < users.size(); i++) {
18506                UserInfo user = users.get(i);
18507                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18508                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18509                }
18510            }
18511        }
18512    }
18513
18514    private Set getProfileIdsLocked(int userId) {
18515        Set userIds = new HashSet<Integer>();
18516        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18517                userId, false /* enabledOnly */);
18518        for (UserInfo user : profiles) {
18519            userIds.add(Integer.valueOf(user.id));
18520        }
18521        return userIds;
18522    }
18523
18524    @Override
18525    public boolean switchUser(final int userId) {
18526        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18527        String userName;
18528        synchronized (this) {
18529            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18530            if (userInfo == null) {
18531                Slog.w(TAG, "No user info for user #" + userId);
18532                return false;
18533            }
18534            if (userInfo.isManagedProfile()) {
18535                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18536                return false;
18537            }
18538            userName = userInfo.name;
18539            mTargetUserId = userId;
18540        }
18541        mHandler.removeMessages(START_USER_SWITCH_MSG);
18542        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18543        return true;
18544    }
18545
18546    private void showUserSwitchDialog(int userId, String userName) {
18547        // The dialog will show and then initiate the user switch by calling startUserInForeground
18548        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18549                true /* above system */);
18550        d.show();
18551    }
18552
18553    private boolean startUser(final int userId, final boolean foreground) {
18554        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18555                != PackageManager.PERMISSION_GRANTED) {
18556            String msg = "Permission Denial: switchUser() from pid="
18557                    + Binder.getCallingPid()
18558                    + ", uid=" + Binder.getCallingUid()
18559                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18560            Slog.w(TAG, msg);
18561            throw new SecurityException(msg);
18562        }
18563
18564        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18565
18566        final long ident = Binder.clearCallingIdentity();
18567        try {
18568            synchronized (this) {
18569                final int oldUserId = mCurrentUserId;
18570                if (oldUserId == userId) {
18571                    return true;
18572                }
18573
18574                mStackSupervisor.setLockTaskModeLocked(null, false);
18575
18576                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18577                if (userInfo == null) {
18578                    Slog.w(TAG, "No user info for user #" + userId);
18579                    return false;
18580                }
18581                if (foreground && userInfo.isManagedProfile()) {
18582                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18583                    return false;
18584                }
18585
18586                if (foreground) {
18587                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18588                            R.anim.screen_user_enter);
18589                }
18590
18591                boolean needStart = false;
18592
18593                // If the user we are switching to is not currently started, then
18594                // we need to start it now.
18595                if (mStartedUsers.get(userId) == null) {
18596                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18597                    updateStartedUserArrayLocked();
18598                    needStart = true;
18599                }
18600
18601                final Integer userIdInt = Integer.valueOf(userId);
18602                mUserLru.remove(userIdInt);
18603                mUserLru.add(userIdInt);
18604
18605                if (foreground) {
18606                    mCurrentUserId = userId;
18607                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18608                    updateCurrentProfileIdsLocked();
18609                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18610                    // Once the internal notion of the active user has switched, we lock the device
18611                    // with the option to show the user switcher on the keyguard.
18612                    mWindowManager.lockNow(null);
18613                } else {
18614                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18615                    updateCurrentProfileIdsLocked();
18616                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18617                    mUserLru.remove(currentUserIdInt);
18618                    mUserLru.add(currentUserIdInt);
18619                }
18620
18621                final UserStartedState uss = mStartedUsers.get(userId);
18622
18623                // Make sure user is in the started state.  If it is currently
18624                // stopping, we need to knock that off.
18625                if (uss.mState == UserStartedState.STATE_STOPPING) {
18626                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18627                    // so we can just fairly silently bring the user back from
18628                    // the almost-dead.
18629                    uss.mState = UserStartedState.STATE_RUNNING;
18630                    updateStartedUserArrayLocked();
18631                    needStart = true;
18632                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18633                    // This means ACTION_SHUTDOWN has been sent, so we will
18634                    // need to treat this as a new boot of the user.
18635                    uss.mState = UserStartedState.STATE_BOOTING;
18636                    updateStartedUserArrayLocked();
18637                    needStart = true;
18638                }
18639
18640                if (uss.mState == UserStartedState.STATE_BOOTING) {
18641                    // Booting up a new user, need to tell system services about it.
18642                    // Note that this is on the same handler as scheduling of broadcasts,
18643                    // which is important because it needs to go first.
18644                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18645                }
18646
18647                if (foreground) {
18648                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18649                            oldUserId));
18650                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18651                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18652                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18653                            oldUserId, userId, uss));
18654                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18655                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18656                }
18657
18658                if (needStart) {
18659                    // Send USER_STARTED broadcast
18660                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18661                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18662                            | Intent.FLAG_RECEIVER_FOREGROUND);
18663                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18664                    broadcastIntentLocked(null, null, intent,
18665                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18666                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18667                }
18668
18669                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18670                    if (userId != UserHandle.USER_OWNER) {
18671                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18672                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18673                        broadcastIntentLocked(null, null, intent, null,
18674                                new IIntentReceiver.Stub() {
18675                                    public void performReceive(Intent intent, int resultCode,
18676                                            String data, Bundle extras, boolean ordered,
18677                                            boolean sticky, int sendingUser) {
18678                                        onUserInitialized(uss, foreground, oldUserId, userId);
18679                                    }
18680                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18681                                true, false, MY_PID, Process.SYSTEM_UID,
18682                                userId);
18683                        uss.initializing = true;
18684                    } else {
18685                        getUserManagerLocked().makeInitialized(userInfo.id);
18686                    }
18687                }
18688
18689                if (foreground) {
18690                    if (!uss.initializing) {
18691                        moveUserToForeground(uss, oldUserId, userId);
18692                    }
18693                } else {
18694                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18695                }
18696
18697                if (needStart) {
18698                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18699                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18700                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18701                    broadcastIntentLocked(null, null, intent,
18702                            null, new IIntentReceiver.Stub() {
18703                                @Override
18704                                public void performReceive(Intent intent, int resultCode, String data,
18705                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18706                                        throws RemoteException {
18707                                }
18708                            }, 0, null, null,
18709                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18710                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18711                }
18712            }
18713        } finally {
18714            Binder.restoreCallingIdentity(ident);
18715        }
18716
18717        return true;
18718    }
18719
18720    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18721        long ident = Binder.clearCallingIdentity();
18722        try {
18723            Intent intent;
18724            if (oldUserId >= 0) {
18725                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18726                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18727                int count = profiles.size();
18728                for (int i = 0; i < count; i++) {
18729                    int profileUserId = profiles.get(i).id;
18730                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18731                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18732                            | Intent.FLAG_RECEIVER_FOREGROUND);
18733                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18734                    broadcastIntentLocked(null, null, intent,
18735                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18736                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18737                }
18738            }
18739            if (newUserId >= 0) {
18740                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18741                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18742                int count = profiles.size();
18743                for (int i = 0; i < count; i++) {
18744                    int profileUserId = profiles.get(i).id;
18745                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18746                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18747                            | Intent.FLAG_RECEIVER_FOREGROUND);
18748                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18749                    broadcastIntentLocked(null, null, intent,
18750                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18751                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18752                }
18753                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18754                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18755                        | Intent.FLAG_RECEIVER_FOREGROUND);
18756                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18757                broadcastIntentLocked(null, null, intent,
18758                        null, null, 0, null, null,
18759                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18760                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18761            }
18762        } finally {
18763            Binder.restoreCallingIdentity(ident);
18764        }
18765    }
18766
18767    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18768            final int newUserId) {
18769        final int N = mUserSwitchObservers.beginBroadcast();
18770        if (N > 0) {
18771            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18772                int mCount = 0;
18773                @Override
18774                public void sendResult(Bundle data) throws RemoteException {
18775                    synchronized (ActivityManagerService.this) {
18776                        if (mCurUserSwitchCallback == this) {
18777                            mCount++;
18778                            if (mCount == N) {
18779                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18780                            }
18781                        }
18782                    }
18783                }
18784            };
18785            synchronized (this) {
18786                uss.switching = true;
18787                mCurUserSwitchCallback = callback;
18788            }
18789            for (int i=0; i<N; i++) {
18790                try {
18791                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18792                            newUserId, callback);
18793                } catch (RemoteException e) {
18794                }
18795            }
18796        } else {
18797            synchronized (this) {
18798                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18799            }
18800        }
18801        mUserSwitchObservers.finishBroadcast();
18802    }
18803
18804    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18805        synchronized (this) {
18806            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18807            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18808        }
18809    }
18810
18811    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18812        mCurUserSwitchCallback = null;
18813        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18814        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18815                oldUserId, newUserId, uss));
18816    }
18817
18818    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18819        synchronized (this) {
18820            if (foreground) {
18821                moveUserToForeground(uss, oldUserId, newUserId);
18822            }
18823        }
18824
18825        completeSwitchAndInitalize(uss, newUserId, true, false);
18826    }
18827
18828    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18829        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18830        if (homeInFront) {
18831            startHomeActivityLocked(newUserId);
18832        } else {
18833            mStackSupervisor.resumeTopActivitiesLocked();
18834        }
18835        EventLogTags.writeAmSwitchUser(newUserId);
18836        getUserManagerLocked().userForeground(newUserId);
18837        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18838    }
18839
18840    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18841        completeSwitchAndInitalize(uss, newUserId, false, true);
18842    }
18843
18844    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18845            boolean clearInitializing, boolean clearSwitching) {
18846        boolean unfrozen = false;
18847        synchronized (this) {
18848            if (clearInitializing) {
18849                uss.initializing = false;
18850                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18851            }
18852            if (clearSwitching) {
18853                uss.switching = false;
18854            }
18855            if (!uss.switching && !uss.initializing) {
18856                mWindowManager.stopFreezingScreen();
18857                unfrozen = true;
18858            }
18859        }
18860        if (unfrozen) {
18861            final int N = mUserSwitchObservers.beginBroadcast();
18862            for (int i=0; i<N; i++) {
18863                try {
18864                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18865                } catch (RemoteException e) {
18866                }
18867            }
18868            mUserSwitchObservers.finishBroadcast();
18869        }
18870    }
18871
18872    void scheduleStartProfilesLocked() {
18873        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18874            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18875                    DateUtils.SECOND_IN_MILLIS);
18876        }
18877    }
18878
18879    void startProfilesLocked() {
18880        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18881        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18882                mCurrentUserId, false /* enabledOnly */);
18883        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18884        for (UserInfo user : profiles) {
18885            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18886                    && user.id != mCurrentUserId) {
18887                toStart.add(user);
18888            }
18889        }
18890        final int n = toStart.size();
18891        int i = 0;
18892        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18893            startUserInBackground(toStart.get(i).id);
18894        }
18895        if (i < n) {
18896            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18897        }
18898    }
18899
18900    void finishUserBoot(UserStartedState uss) {
18901        synchronized (this) {
18902            if (uss.mState == UserStartedState.STATE_BOOTING
18903                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18904                uss.mState = UserStartedState.STATE_RUNNING;
18905                final int userId = uss.mHandle.getIdentifier();
18906                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18907                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18908                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18909                broadcastIntentLocked(null, null, intent,
18910                        null, null, 0, null, null,
18911                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18912                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18913            }
18914        }
18915    }
18916
18917    void finishUserSwitch(UserStartedState uss) {
18918        synchronized (this) {
18919            finishUserBoot(uss);
18920
18921            startProfilesLocked();
18922
18923            int num = mUserLru.size();
18924            int i = 0;
18925            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18926                Integer oldUserId = mUserLru.get(i);
18927                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18928                if (oldUss == null) {
18929                    // Shouldn't happen, but be sane if it does.
18930                    mUserLru.remove(i);
18931                    num--;
18932                    continue;
18933                }
18934                if (oldUss.mState == UserStartedState.STATE_STOPPING
18935                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18936                    // This user is already stopping, doesn't count.
18937                    num--;
18938                    i++;
18939                    continue;
18940                }
18941                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18942                    // Owner and current can't be stopped, but count as running.
18943                    i++;
18944                    continue;
18945                }
18946                // This is a user to be stopped.
18947                stopUserLocked(oldUserId, null);
18948                num--;
18949                i++;
18950            }
18951        }
18952    }
18953
18954    @Override
18955    public int stopUser(final int userId, final IStopUserCallback callback) {
18956        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18957                != PackageManager.PERMISSION_GRANTED) {
18958            String msg = "Permission Denial: switchUser() from pid="
18959                    + Binder.getCallingPid()
18960                    + ", uid=" + Binder.getCallingUid()
18961                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18962            Slog.w(TAG, msg);
18963            throw new SecurityException(msg);
18964        }
18965        if (userId <= 0) {
18966            throw new IllegalArgumentException("Can't stop primary user " + userId);
18967        }
18968        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18969        synchronized (this) {
18970            return stopUserLocked(userId, callback);
18971        }
18972    }
18973
18974    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18975        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18976        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18977            return ActivityManager.USER_OP_IS_CURRENT;
18978        }
18979
18980        final UserStartedState uss = mStartedUsers.get(userId);
18981        if (uss == null) {
18982            // User is not started, nothing to do...  but we do need to
18983            // callback if requested.
18984            if (callback != null) {
18985                mHandler.post(new Runnable() {
18986                    @Override
18987                    public void run() {
18988                        try {
18989                            callback.userStopped(userId);
18990                        } catch (RemoteException e) {
18991                        }
18992                    }
18993                });
18994            }
18995            return ActivityManager.USER_OP_SUCCESS;
18996        }
18997
18998        if (callback != null) {
18999            uss.mStopCallbacks.add(callback);
19000        }
19001
19002        if (uss.mState != UserStartedState.STATE_STOPPING
19003                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19004            uss.mState = UserStartedState.STATE_STOPPING;
19005            updateStartedUserArrayLocked();
19006
19007            long ident = Binder.clearCallingIdentity();
19008            try {
19009                // We are going to broadcast ACTION_USER_STOPPING and then
19010                // once that is done send a final ACTION_SHUTDOWN and then
19011                // stop the user.
19012                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19013                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19014                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19015                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19016                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19017                // This is the result receiver for the final shutdown broadcast.
19018                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19019                    @Override
19020                    public void performReceive(Intent intent, int resultCode, String data,
19021                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19022                        finishUserStop(uss);
19023                    }
19024                };
19025                // This is the result receiver for the initial stopping broadcast.
19026                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19027                    @Override
19028                    public void performReceive(Intent intent, int resultCode, String data,
19029                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19030                        // On to the next.
19031                        synchronized (ActivityManagerService.this) {
19032                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19033                                // Whoops, we are being started back up.  Abort, abort!
19034                                return;
19035                            }
19036                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19037                        }
19038                        mBatteryStatsService.noteEvent(
19039                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19040                                Integer.toString(userId), userId);
19041                        mSystemServiceManager.stopUser(userId);
19042                        broadcastIntentLocked(null, null, shutdownIntent,
19043                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19044                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19045                    }
19046                };
19047                // Kick things off.
19048                broadcastIntentLocked(null, null, stoppingIntent,
19049                        null, stoppingReceiver, 0, null, null,
19050                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19051                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19052            } finally {
19053                Binder.restoreCallingIdentity(ident);
19054            }
19055        }
19056
19057        return ActivityManager.USER_OP_SUCCESS;
19058    }
19059
19060    void finishUserStop(UserStartedState uss) {
19061        final int userId = uss.mHandle.getIdentifier();
19062        boolean stopped;
19063        ArrayList<IStopUserCallback> callbacks;
19064        synchronized (this) {
19065            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19066            if (mStartedUsers.get(userId) != uss) {
19067                stopped = false;
19068            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19069                stopped = false;
19070            } else {
19071                stopped = true;
19072                // User can no longer run.
19073                mStartedUsers.remove(userId);
19074                mUserLru.remove(Integer.valueOf(userId));
19075                updateStartedUserArrayLocked();
19076
19077                // Clean up all state and processes associated with the user.
19078                // Kill all the processes for the user.
19079                forceStopUserLocked(userId, "finish user");
19080            }
19081
19082            // Explicitly remove the old information in mRecentTasks.
19083            removeRecentTasksForUserLocked(userId);
19084        }
19085
19086        for (int i=0; i<callbacks.size(); i++) {
19087            try {
19088                if (stopped) callbacks.get(i).userStopped(userId);
19089                else callbacks.get(i).userStopAborted(userId);
19090            } catch (RemoteException e) {
19091            }
19092        }
19093
19094        if (stopped) {
19095            mSystemServiceManager.cleanupUser(userId);
19096            synchronized (this) {
19097                mStackSupervisor.removeUserLocked(userId);
19098            }
19099        }
19100    }
19101
19102    @Override
19103    public UserInfo getCurrentUser() {
19104        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19105                != PackageManager.PERMISSION_GRANTED) && (
19106                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19107                != PackageManager.PERMISSION_GRANTED)) {
19108            String msg = "Permission Denial: getCurrentUser() from pid="
19109                    + Binder.getCallingPid()
19110                    + ", uid=" + Binder.getCallingUid()
19111                    + " requires " + INTERACT_ACROSS_USERS;
19112            Slog.w(TAG, msg);
19113            throw new SecurityException(msg);
19114        }
19115        synchronized (this) {
19116            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19117            return getUserManagerLocked().getUserInfo(userId);
19118        }
19119    }
19120
19121    int getCurrentUserIdLocked() {
19122        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19123    }
19124
19125    @Override
19126    public boolean isUserRunning(int userId, boolean orStopped) {
19127        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19128                != PackageManager.PERMISSION_GRANTED) {
19129            String msg = "Permission Denial: isUserRunning() from pid="
19130                    + Binder.getCallingPid()
19131                    + ", uid=" + Binder.getCallingUid()
19132                    + " requires " + INTERACT_ACROSS_USERS;
19133            Slog.w(TAG, msg);
19134            throw new SecurityException(msg);
19135        }
19136        synchronized (this) {
19137            return isUserRunningLocked(userId, orStopped);
19138        }
19139    }
19140
19141    boolean isUserRunningLocked(int userId, boolean orStopped) {
19142        UserStartedState state = mStartedUsers.get(userId);
19143        if (state == null) {
19144            return false;
19145        }
19146        if (orStopped) {
19147            return true;
19148        }
19149        return state.mState != UserStartedState.STATE_STOPPING
19150                && state.mState != UserStartedState.STATE_SHUTDOWN;
19151    }
19152
19153    @Override
19154    public int[] getRunningUserIds() {
19155        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19156                != PackageManager.PERMISSION_GRANTED) {
19157            String msg = "Permission Denial: isUserRunning() from pid="
19158                    + Binder.getCallingPid()
19159                    + ", uid=" + Binder.getCallingUid()
19160                    + " requires " + INTERACT_ACROSS_USERS;
19161            Slog.w(TAG, msg);
19162            throw new SecurityException(msg);
19163        }
19164        synchronized (this) {
19165            return mStartedUserArray;
19166        }
19167    }
19168
19169    private void updateStartedUserArrayLocked() {
19170        int num = 0;
19171        for (int i=0; i<mStartedUsers.size();  i++) {
19172            UserStartedState uss = mStartedUsers.valueAt(i);
19173            // This list does not include stopping users.
19174            if (uss.mState != UserStartedState.STATE_STOPPING
19175                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19176                num++;
19177            }
19178        }
19179        mStartedUserArray = new int[num];
19180        num = 0;
19181        for (int i=0; i<mStartedUsers.size();  i++) {
19182            UserStartedState uss = mStartedUsers.valueAt(i);
19183            if (uss.mState != UserStartedState.STATE_STOPPING
19184                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19185                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19186                num++;
19187            }
19188        }
19189    }
19190
19191    @Override
19192    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19193        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19194                != PackageManager.PERMISSION_GRANTED) {
19195            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19196                    + Binder.getCallingPid()
19197                    + ", uid=" + Binder.getCallingUid()
19198                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19199            Slog.w(TAG, msg);
19200            throw new SecurityException(msg);
19201        }
19202
19203        mUserSwitchObservers.register(observer);
19204    }
19205
19206    @Override
19207    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19208        mUserSwitchObservers.unregister(observer);
19209    }
19210
19211    private boolean userExists(int userId) {
19212        if (userId == 0) {
19213            return true;
19214        }
19215        UserManagerService ums = getUserManagerLocked();
19216        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19217    }
19218
19219    int[] getUsersLocked() {
19220        UserManagerService ums = getUserManagerLocked();
19221        return ums != null ? ums.getUserIds() : new int[] { 0 };
19222    }
19223
19224    UserManagerService getUserManagerLocked() {
19225        if (mUserManager == null) {
19226            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19227            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19228        }
19229        return mUserManager;
19230    }
19231
19232    private int applyUserId(int uid, int userId) {
19233        return UserHandle.getUid(userId, uid);
19234    }
19235
19236    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19237        if (info == null) return null;
19238        ApplicationInfo newInfo = new ApplicationInfo(info);
19239        newInfo.uid = applyUserId(info.uid, userId);
19240        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19241                + info.packageName;
19242        return newInfo;
19243    }
19244
19245    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19246        if (aInfo == null
19247                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19248            return aInfo;
19249        }
19250
19251        ActivityInfo info = new ActivityInfo(aInfo);
19252        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19253        return info;
19254    }
19255
19256    private final class LocalService extends ActivityManagerInternal {
19257        @Override
19258        public void onWakefulnessChanged(int wakefulness) {
19259            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19260        }
19261
19262        @Override
19263        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19264                String processName, String abiOverride, int uid, Runnable crashHandler) {
19265            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19266                    processName, abiOverride, uid, crashHandler);
19267        }
19268    }
19269
19270    /**
19271     * An implementation of IAppTask, that allows an app to manage its own tasks via
19272     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19273     * only the process that calls getAppTasks() can call the AppTask methods.
19274     */
19275    class AppTaskImpl extends IAppTask.Stub {
19276        private int mTaskId;
19277        private int mCallingUid;
19278
19279        public AppTaskImpl(int taskId, int callingUid) {
19280            mTaskId = taskId;
19281            mCallingUid = callingUid;
19282        }
19283
19284        private void checkCaller() {
19285            if (mCallingUid != Binder.getCallingUid()) {
19286                throw new SecurityException("Caller " + mCallingUid
19287                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19288            }
19289        }
19290
19291        @Override
19292        public void finishAndRemoveTask() {
19293            checkCaller();
19294
19295            synchronized (ActivityManagerService.this) {
19296                long origId = Binder.clearCallingIdentity();
19297                try {
19298                    if (!removeTaskByIdLocked(mTaskId, false)) {
19299                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19300                    }
19301                } finally {
19302                    Binder.restoreCallingIdentity(origId);
19303                }
19304            }
19305        }
19306
19307        @Override
19308        public ActivityManager.RecentTaskInfo getTaskInfo() {
19309            checkCaller();
19310
19311            synchronized (ActivityManagerService.this) {
19312                long origId = Binder.clearCallingIdentity();
19313                try {
19314                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19315                    if (tr == null) {
19316                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19317                    }
19318                    return createRecentTaskInfoFromTaskRecord(tr);
19319                } finally {
19320                    Binder.restoreCallingIdentity(origId);
19321                }
19322            }
19323        }
19324
19325        @Override
19326        public void moveToFront() {
19327            checkCaller();
19328
19329            final TaskRecord tr;
19330            synchronized (ActivityManagerService.this) {
19331                tr = recentTaskForIdLocked(mTaskId);
19332                if (tr == null) {
19333                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19334                }
19335                if (tr.getRootActivity() != null) {
19336                    moveTaskToFrontLocked(tr.taskId, 0, null);
19337                    return;
19338                }
19339            }
19340
19341            startActivityFromRecentsInner(tr.taskId, null);
19342        }
19343
19344        @Override
19345        public int startActivity(IBinder whoThread, String callingPackage,
19346                Intent intent, String resolvedType, Bundle options) {
19347            checkCaller();
19348
19349            int callingUser = UserHandle.getCallingUserId();
19350            TaskRecord tr;
19351            IApplicationThread appThread;
19352            synchronized (ActivityManagerService.this) {
19353                tr = recentTaskForIdLocked(mTaskId);
19354                if (tr == null) {
19355                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19356                }
19357                appThread = ApplicationThreadNative.asInterface(whoThread);
19358                if (appThread == null) {
19359                    throw new IllegalArgumentException("Bad app thread " + appThread);
19360                }
19361            }
19362            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19363                    resolvedType, null, null, null, null, 0, 0, null, null,
19364                    null, options, callingUser, null, tr);
19365        }
19366
19367        @Override
19368        public void setExcludeFromRecents(boolean exclude) {
19369            checkCaller();
19370
19371            synchronized (ActivityManagerService.this) {
19372                long origId = Binder.clearCallingIdentity();
19373                try {
19374                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19375                    if (tr == null) {
19376                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19377                    }
19378                    Intent intent = tr.getBaseIntent();
19379                    if (exclude) {
19380                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19381                    } else {
19382                        intent.setFlags(intent.getFlags()
19383                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19384                    }
19385                } finally {
19386                    Binder.restoreCallingIdentity(origId);
19387                }
19388            }
19389        }
19390    }
19391}
19392