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;
33import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ITaskStackListener;
42import android.app.ProfilerInfo;
43import android.app.admin.DevicePolicyManager;
44import android.app.usage.UsageEvents;
45import android.app.usage.UsageStatsManagerInternal;
46import android.appwidget.AppWidgetManager;
47import android.content.res.Resources;
48import android.graphics.Bitmap;
49import android.graphics.Point;
50import android.graphics.Rect;
51import android.os.BatteryStats;
52import android.os.PersistableBundle;
53import android.os.storage.IMountService;
54import android.os.storage.StorageManager;
55import android.service.voice.IVoiceInteractionSession;
56import android.util.ArrayMap;
57import android.util.ArraySet;
58import android.util.SparseIntArray;
59
60import android.view.Display;
61import com.android.internal.R;
62import com.android.internal.annotations.GuardedBy;
63import com.android.internal.app.IAppOpsService;
64import com.android.internal.app.IVoiceInteractor;
65import com.android.internal.app.ProcessMap;
66import com.android.internal.app.ProcessStats;
67import com.android.internal.os.BackgroundThread;
68import com.android.internal.os.BatteryStatsImpl;
69import com.android.internal.os.ProcessCpuTracker;
70import com.android.internal.os.TransferPipe;
71import com.android.internal.os.Zygote;
72import com.android.internal.util.FastPrintWriter;
73import com.android.internal.util.FastXmlSerializer;
74import com.android.internal.util.MemInfoReader;
75import com.android.internal.util.Preconditions;
76import com.android.server.AppOpsService;
77import com.android.server.AttributeCache;
78import com.android.server.IntentResolver;
79import com.android.server.LocalServices;
80import com.android.server.ServiceThread;
81import com.android.server.SystemService;
82import com.android.server.SystemServiceManager;
83import com.android.server.Watchdog;
84import com.android.server.am.ActivityStack.ActivityState;
85import com.android.server.firewall.IntentFirewall;
86import com.android.server.pm.Installer;
87import com.android.server.pm.UserManagerService;
88import com.android.server.statusbar.StatusBarManagerInternal;
89import com.android.server.wm.AppTransition;
90import com.android.server.wm.WindowManagerService;
91import com.google.android.collect.Lists;
92import com.google.android.collect.Maps;
93
94import libcore.io.IoUtils;
95
96import org.xmlpull.v1.XmlPullParser;
97import org.xmlpull.v1.XmlPullParserException;
98import org.xmlpull.v1.XmlSerializer;
99
100import android.app.Activity;
101import android.app.ActivityManager;
102import android.app.ActivityManager.RunningTaskInfo;
103import android.app.ActivityManager.StackInfo;
104import android.app.ActivityManagerInternal;
105import android.app.ActivityManagerNative;
106import android.app.ActivityOptions;
107import android.app.ActivityThread;
108import android.app.AlertDialog;
109import android.app.AppGlobals;
110import android.app.ApplicationErrorReport;
111import android.app.Dialog;
112import android.app.IActivityController;
113import android.app.IApplicationThread;
114import android.app.IInstrumentationWatcher;
115import android.app.INotificationManager;
116import android.app.IProcessObserver;
117import android.app.IServiceConnection;
118import android.app.IStopUserCallback;
119import android.app.IUiAutomationConnection;
120import android.app.IUserSwitchObserver;
121import android.app.Instrumentation;
122import android.app.Notification;
123import android.app.NotificationManager;
124import android.app.PendingIntent;
125import android.app.backup.IBackupManager;
126import android.content.ActivityNotFoundException;
127import android.content.BroadcastReceiver;
128import android.content.ClipData;
129import android.content.ComponentCallbacks2;
130import android.content.ComponentName;
131import android.content.ContentProvider;
132import android.content.ContentResolver;
133import android.content.Context;
134import android.content.DialogInterface;
135import android.content.IContentProvider;
136import android.content.IIntentReceiver;
137import android.content.IIntentSender;
138import android.content.Intent;
139import android.content.IntentFilter;
140import android.content.IntentSender;
141import android.content.pm.ActivityInfo;
142import android.content.pm.ApplicationInfo;
143import android.content.pm.ConfigurationInfo;
144import android.content.pm.IPackageDataObserver;
145import android.content.pm.IPackageManager;
146import android.content.pm.InstrumentationInfo;
147import android.content.pm.PackageInfo;
148import android.content.pm.PackageManager;
149import android.content.pm.ParceledListSlice;
150import android.content.pm.UserInfo;
151import android.content.pm.PackageManager.NameNotFoundException;
152import android.content.pm.PathPermission;
153import android.content.pm.ProviderInfo;
154import android.content.pm.ResolveInfo;
155import android.content.pm.ServiceInfo;
156import android.content.res.CompatibilityInfo;
157import android.content.res.Configuration;
158import android.net.Proxy;
159import android.net.ProxyInfo;
160import android.net.Uri;
161import android.os.Binder;
162import android.os.Build;
163import android.os.Bundle;
164import android.os.Debug;
165import android.os.DropBoxManager;
166import android.os.Environment;
167import android.os.FactoryTest;
168import android.os.FileObserver;
169import android.os.FileUtils;
170import android.os.Handler;
171import android.os.IBinder;
172import android.os.IPermissionController;
173import android.os.IRemoteCallback;
174import android.os.IUserManager;
175import android.os.Looper;
176import android.os.Message;
177import android.os.Parcel;
178import android.os.ParcelFileDescriptor;
179import android.os.PowerManagerInternal;
180import android.os.Process;
181import android.os.RemoteCallbackList;
182import android.os.RemoteException;
183import android.os.SELinux;
184import android.os.ServiceManager;
185import android.os.StrictMode;
186import android.os.SystemClock;
187import android.os.SystemProperties;
188import android.os.UpdateLock;
189import android.os.UserHandle;
190import android.os.UserManager;
191import android.provider.Settings;
192import android.text.format.DateUtils;
193import android.text.format.Time;
194import android.util.AtomicFile;
195import android.util.EventLog;
196import android.util.Log;
197import android.util.Pair;
198import android.util.PrintWriterPrinter;
199import android.util.Slog;
200import android.util.SparseArray;
201import android.util.TimeUtils;
202import android.util.Xml;
203import android.view.Gravity;
204import android.view.LayoutInflater;
205import android.view.View;
206import android.view.WindowManager;
207
208import dalvik.system.VMRuntime;
209
210import java.io.BufferedInputStream;
211import java.io.BufferedOutputStream;
212import java.io.DataInputStream;
213import java.io.DataOutputStream;
214import java.io.File;
215import java.io.FileDescriptor;
216import java.io.FileInputStream;
217import java.io.FileNotFoundException;
218import java.io.FileOutputStream;
219import java.io.IOException;
220import java.io.InputStreamReader;
221import java.io.PrintWriter;
222import java.io.StringWriter;
223import java.lang.ref.WeakReference;
224import java.util.ArrayList;
225import java.util.Arrays;
226import java.util.Collections;
227import java.util.Comparator;
228import java.util.HashMap;
229import java.util.HashSet;
230import java.util.Iterator;
231import java.util.List;
232import java.util.Locale;
233import java.util.Map;
234import java.util.Set;
235import java.util.concurrent.atomic.AtomicBoolean;
236import java.util.concurrent.atomic.AtomicLong;
237
238public final class ActivityManagerService extends ActivityManagerNative
239        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
240
241    private static final String USER_DATA_DIR = "/data/user/";
242    // File that stores last updated system version and called preboot receivers
243    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
244
245    static final String TAG = "ActivityManager";
246    static final String TAG_MU = "ActivityManagerServiceMU";
247    static final boolean DEBUG = false;
248    static final boolean localLOGV = DEBUG;
249    static final boolean DEBUG_BACKUP = localLOGV || false;
250    static final boolean DEBUG_BROADCAST = localLOGV || false;
251    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
252    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
253    static final boolean DEBUG_CLEANUP = localLOGV || false;
254    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
255    static final boolean DEBUG_FOCUS = false;
256    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
257    static final boolean DEBUG_MU = localLOGV || false;
258    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
259    static final boolean DEBUG_LRU = localLOGV || false;
260    static final boolean DEBUG_PAUSE = localLOGV || false;
261    static final boolean DEBUG_POWER = localLOGV || false;
262    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
263    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
264    static final boolean DEBUG_PROCESSES = localLOGV || false;
265    static final boolean DEBUG_PROVIDER = localLOGV || false;
266    static final boolean DEBUG_RESULTS = localLOGV || false;
267    static final boolean DEBUG_SERVICE = localLOGV || false;
268    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
269    static final boolean DEBUG_STACK = localLOGV || false;
270    static final boolean DEBUG_SWITCH = localLOGV || false;
271    static final boolean DEBUG_TASKS = localLOGV || false;
272    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
273    static final boolean DEBUG_TRANSITION = localLOGV || false;
274    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
275    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
276    static final boolean DEBUG_VISBILITY = localLOGV || false;
277    static final boolean DEBUG_PSS = localLOGV || false;
278    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
279    static final boolean DEBUG_RECENTS = localLOGV || false;
280    static final boolean VALIDATE_TOKENS = false;
281    static final boolean SHOW_ACTIVITY_START_TIME = true;
282
283    // Control over CPU and battery monitoring.
284    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
285    static final boolean MONITOR_CPU_USAGE = true;
286    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
287    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
288    static final boolean MONITOR_THREAD_CPU_USAGE = false;
289
290    // The flags that are set for all calls we make to the package manager.
291    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
292
293    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
294
295    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
296
297    // Maximum number recent bitmaps to keep in memory.
298    static final int MAX_RECENT_BITMAPS = 3;
299
300    // Amount of time after a call to stopAppSwitches() during which we will
301    // prevent further untrusted switches from happening.
302    static final long APP_SWITCH_DELAY_TIME = 5*1000;
303
304    // How long we wait for a launched process to attach to the activity manager
305    // before we decide it's never going to come up for real.
306    static final int PROC_START_TIMEOUT = 10*1000;
307
308    // How long we wait for a launched process to attach to the activity manager
309    // before we decide it's never going to come up for real, when the process was
310    // started with a wrapper for instrumentation (such as Valgrind) because it
311    // could take much longer than usual.
312    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
313
314    // How long to wait after going idle before forcing apps to GC.
315    static final int GC_TIMEOUT = 5*1000;
316
317    // The minimum amount of time between successive GC requests for a process.
318    static final int GC_MIN_INTERVAL = 60*1000;
319
320    // The minimum amount of time between successive PSS requests for a process.
321    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
322
323    // The minimum amount of time between successive PSS requests for a process
324    // when the request is due to the memory state being lowered.
325    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
326
327    // The rate at which we check for apps using excessive power -- 15 mins.
328    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
329
330    // The minimum sample duration we will allow before deciding we have
331    // enough data on wake locks to start killing things.
332    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
333
334    // The minimum sample duration we will allow before deciding we have
335    // enough data on CPU usage to start killing things.
336    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
337
338    // How long we allow a receiver to run before giving up on it.
339    static final int BROADCAST_FG_TIMEOUT = 10*1000;
340    static final int BROADCAST_BG_TIMEOUT = 60*1000;
341
342    // How long we wait until we timeout on key dispatching.
343    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
344
345    // How long we wait until we timeout on key dispatching during instrumentation.
346    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
347
348    // Amount of time we wait for observers to handle a user switch before
349    // giving up on them and unfreezing the screen.
350    static final int USER_SWITCH_TIMEOUT = 2*1000;
351
352    // Maximum number of users we allow to be running at a time.
353    static final int MAX_RUNNING_USERS = 3;
354
355    // How long to wait in getAssistContextExtras for the activity and foreground services
356    // to respond with the result.
357    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
358
359    // Maximum number of persisted Uri grants a package is allowed
360    static final int MAX_PERSISTED_URI_GRANTS = 128;
361
362    static final int MY_PID = Process.myPid();
363
364    static final String[] EMPTY_STRING_ARRAY = new String[0];
365
366    // How many bytes to write into the dropbox log before truncating
367    static final int DROPBOX_MAX_SIZE = 256 * 1024;
368
369    // Access modes for handleIncomingUser.
370    static final int ALLOW_NON_FULL = 0;
371    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
372    static final int ALLOW_FULL_ONLY = 2;
373
374    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
375
376    // Delay in notifying task stack change listeners (in millis)
377    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
378
379    /** All system services */
380    SystemServiceManager mSystemServiceManager;
381
382    private Installer mInstaller;
383
384    /** Run all ActivityStacks through this */
385    ActivityStackSupervisor mStackSupervisor;
386
387    /** Task stack change listeners. */
388    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
389            new RemoteCallbackList<ITaskStackListener>();
390
391    public IntentFirewall mIntentFirewall;
392
393    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
394    // default actuion automatically.  Important for devices without direct input
395    // devices.
396    private boolean mShowDialogs = true;
397
398    BroadcastQueue mFgBroadcastQueue;
399    BroadcastQueue mBgBroadcastQueue;
400    // Convenient for easy iteration over the queues. Foreground is first
401    // so that dispatch of foreground broadcasts gets precedence.
402    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
403
404    BroadcastQueue broadcastQueueForIntent(Intent intent) {
405        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
406        if (DEBUG_BACKGROUND_BROADCAST) {
407            Slog.i(TAG, "Broadcast intent " + intent + " on "
408                    + (isFg ? "foreground" : "background")
409                    + " queue");
410        }
411        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
412    }
413
414    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
415        for (BroadcastQueue queue : mBroadcastQueues) {
416            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
417            if (r != null) {
418                return r;
419            }
420        }
421        return null;
422    }
423
424    /**
425     * Activity we have told the window manager to have key focus.
426     */
427    ActivityRecord mFocusedActivity = null;
428
429    /**
430     * List of intents that were used to start the most recent tasks.
431     */
432    ArrayList<TaskRecord> mRecentTasks;
433    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
434
435    /**
436     * For addAppTask: cached of the last activity component that was added.
437     */
438    ComponentName mLastAddedTaskComponent;
439
440    /**
441     * For addAppTask: cached of the last activity uid that was added.
442     */
443    int mLastAddedTaskUid;
444
445    /**
446     * For addAppTask: cached of the last ActivityInfo that was added.
447     */
448    ActivityInfo mLastAddedTaskActivity;
449
450    public class PendingAssistExtras extends Binder implements Runnable {
451        public final ActivityRecord activity;
452        public final Bundle extras;
453        public final Intent intent;
454        public final String hint;
455        public final int userHandle;
456        public boolean haveResult = false;
457        public Bundle result = null;
458        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
459                String _hint, int _userHandle) {
460            activity = _activity;
461            extras = _extras;
462            intent = _intent;
463            hint = _hint;
464            userHandle = _userHandle;
465        }
466        @Override
467        public void run() {
468            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
469            synchronized (this) {
470                haveResult = true;
471                notifyAll();
472            }
473        }
474    }
475
476    final ArrayList<PendingAssistExtras> mPendingAssistExtras
477            = new ArrayList<PendingAssistExtras>();
478
479    /**
480     * Process management.
481     */
482    final ProcessList mProcessList = new ProcessList();
483
484    /**
485     * All of the applications we currently have running organized by name.
486     * The keys are strings of the application package name (as
487     * returned by the package manager), and the keys are ApplicationRecord
488     * objects.
489     */
490    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
491
492    /**
493     * Tracking long-term execution of processes to look for abuse and other
494     * bad app behavior.
495     */
496    final ProcessStatsService mProcessStats;
497
498    /**
499     * The currently running isolated processes.
500     */
501    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
502
503    /**
504     * Counter for assigning isolated process uids, to avoid frequently reusing the
505     * same ones.
506     */
507    int mNextIsolatedProcessUid = 0;
508
509    /**
510     * The currently running heavy-weight process, if any.
511     */
512    ProcessRecord mHeavyWeightProcess = null;
513
514    /**
515     * The last time that various processes have crashed.
516     */
517    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
518
519    /**
520     * Information about a process that is currently marked as bad.
521     */
522    static final class BadProcessInfo {
523        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
524            this.time = time;
525            this.shortMsg = shortMsg;
526            this.longMsg = longMsg;
527            this.stack = stack;
528        }
529
530        final long time;
531        final String shortMsg;
532        final String longMsg;
533        final String stack;
534    }
535
536    /**
537     * Set of applications that we consider to be bad, and will reject
538     * incoming broadcasts from (which the user has no control over).
539     * Processes are added to this set when they have crashed twice within
540     * a minimum amount of time; they are removed from it when they are
541     * later restarted (hopefully due to some user action).  The value is the
542     * time it was added to the list.
543     */
544    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
545
546    /**
547     * All of the processes we currently have running organized by pid.
548     * The keys are the pid running the application.
549     *
550     * <p>NOTE: This object is protected by its own lock, NOT the global
551     * activity manager lock!
552     */
553    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
554
555    /**
556     * All of the processes that have been forced to be foreground.  The key
557     * is the pid of the caller who requested it (we hold a death
558     * link on it).
559     */
560    abstract class ForegroundToken implements IBinder.DeathRecipient {
561        int pid;
562        IBinder token;
563    }
564    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
565
566    /**
567     * List of records for processes that someone had tried to start before the
568     * system was ready.  We don't start them at that point, but ensure they
569     * are started by the time booting is complete.
570     */
571    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
572
573    /**
574     * List of persistent applications that are in the process
575     * of being started.
576     */
577    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
578
579    /**
580     * Processes that are being forcibly torn down.
581     */
582    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
583
584    /**
585     * List of running applications, sorted by recent usage.
586     * The first entry in the list is the least recently used.
587     */
588    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
589
590    /**
591     * Where in mLruProcesses that the processes hosting activities start.
592     */
593    int mLruProcessActivityStart = 0;
594
595    /**
596     * Where in mLruProcesses that the processes hosting services start.
597     * This is after (lower index) than mLruProcessesActivityStart.
598     */
599    int mLruProcessServiceStart = 0;
600
601    /**
602     * List of processes that should gc as soon as things are idle.
603     */
604    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
605
606    /**
607     * Processes we want to collect PSS data from.
608     */
609    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
610
611    /**
612     * Last time we requested PSS data of all processes.
613     */
614    long mLastFullPssTime = SystemClock.uptimeMillis();
615
616    /**
617     * If set, the next time we collect PSS data we should do a full collection
618     * with data from native processes and the kernel.
619     */
620    boolean mFullPssPending = false;
621
622    /**
623     * This is the process holding what we currently consider to be
624     * the "home" activity.
625     */
626    ProcessRecord mHomeProcess;
627
628    /**
629     * This is the process holding the activity the user last visited that
630     * is in a different process from the one they are currently in.
631     */
632    ProcessRecord mPreviousProcess;
633
634    /**
635     * The time at which the previous process was last visible.
636     */
637    long mPreviousProcessVisibleTime;
638
639    /**
640     * Which uses have been started, so are allowed to run code.
641     */
642    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
643
644    /**
645     * LRU list of history of current users.  Most recently current is at the end.
646     */
647    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
648
649    /**
650     * Constant array of the users that are currently started.
651     */
652    int[] mStartedUserArray = new int[] { 0 };
653
654    /**
655     * Registered observers of the user switching mechanics.
656     */
657    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
658            = new RemoteCallbackList<IUserSwitchObserver>();
659
660    /**
661     * Currently active user switch.
662     */
663    Object mCurUserSwitchCallback;
664
665    /**
666     * Packages that the user has asked to have run in screen size
667     * compatibility mode instead of filling the screen.
668     */
669    final CompatModePackages mCompatModePackages;
670
671    /**
672     * Set of IntentSenderRecord objects that are currently active.
673     */
674    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
675            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
676
677    /**
678     * Fingerprints (hashCode()) of stack traces that we've
679     * already logged DropBox entries for.  Guarded by itself.  If
680     * something (rogue user app) forces this over
681     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
682     */
683    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
684    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
685
686    /**
687     * Strict Mode background batched logging state.
688     *
689     * The string buffer is guarded by itself, and its lock is also
690     * used to determine if another batched write is already
691     * in-flight.
692     */
693    private final StringBuilder mStrictModeBuffer = new StringBuilder();
694
695    /**
696     * Keeps track of all IIntentReceivers that have been registered for
697     * broadcasts.  Hash keys are the receiver IBinder, hash value is
698     * a ReceiverList.
699     */
700    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
701            new HashMap<IBinder, ReceiverList>();
702
703    /**
704     * Resolver for broadcast intents to registered receivers.
705     * Holds BroadcastFilter (subclass of IntentFilter).
706     */
707    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
708            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
709        @Override
710        protected boolean allowFilterResult(
711                BroadcastFilter filter, List<BroadcastFilter> dest) {
712            IBinder target = filter.receiverList.receiver.asBinder();
713            for (int i=dest.size()-1; i>=0; i--) {
714                if (dest.get(i).receiverList.receiver.asBinder() == target) {
715                    return false;
716                }
717            }
718            return true;
719        }
720
721        @Override
722        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
723            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
724                    || userId == filter.owningUserId) {
725                return super.newResult(filter, match, userId);
726            }
727            return null;
728        }
729
730        @Override
731        protected BroadcastFilter[] newArray(int size) {
732            return new BroadcastFilter[size];
733        }
734
735        @Override
736        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
737            return packageName.equals(filter.packageName);
738        }
739    };
740
741    /**
742     * State of all active sticky broadcasts per user.  Keys are the action of the
743     * sticky Intent, values are an ArrayList of all broadcasted intents with
744     * that action (which should usually be one).  The SparseArray is keyed
745     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
746     * for stickies that are sent to all users.
747     */
748    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
749            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
750
751    final ActiveServices mServices;
752
753    final static class Association {
754        final int mSourceUid;
755        final String mSourceProcess;
756        final int mTargetUid;
757        final ComponentName mTargetComponent;
758        final String mTargetProcess;
759
760        int mCount;
761        long mTime;
762
763        int mNesting;
764        long mStartTime;
765
766        Association(int sourceUid, String sourceProcess, int targetUid,
767                ComponentName targetComponent, String targetProcess) {
768            mSourceUid = sourceUid;
769            mSourceProcess = sourceProcess;
770            mTargetUid = targetUid;
771            mTargetComponent = targetComponent;
772            mTargetProcess = targetProcess;
773        }
774    }
775
776    /**
777     * When service association tracking is enabled, this is all of the associations we
778     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
779     * -> association data.
780     */
781    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
782            mAssociations = new SparseArray<>();
783    boolean mTrackingAssociations;
784
785    /**
786     * Backup/restore process management
787     */
788    String mBackupAppName = null;
789    BackupRecord mBackupTarget = null;
790
791    final ProviderMap mProviderMap;
792
793    /**
794     * List of content providers who have clients waiting for them.  The
795     * application is currently being launched and the provider will be
796     * removed from this list once it is published.
797     */
798    final ArrayList<ContentProviderRecord> mLaunchingProviders
799            = new ArrayList<ContentProviderRecord>();
800
801    /**
802     * File storing persisted {@link #mGrantedUriPermissions}.
803     */
804    private final AtomicFile mGrantFile;
805
806    /** XML constants used in {@link #mGrantFile} */
807    private static final String TAG_URI_GRANTS = "uri-grants";
808    private static final String TAG_URI_GRANT = "uri-grant";
809    private static final String ATTR_USER_HANDLE = "userHandle";
810    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
811    private static final String ATTR_TARGET_USER_ID = "targetUserId";
812    private static final String ATTR_SOURCE_PKG = "sourcePkg";
813    private static final String ATTR_TARGET_PKG = "targetPkg";
814    private static final String ATTR_URI = "uri";
815    private static final String ATTR_MODE_FLAGS = "modeFlags";
816    private static final String ATTR_CREATED_TIME = "createdTime";
817    private static final String ATTR_PREFIX = "prefix";
818
819    /**
820     * Global set of specific {@link Uri} permissions that have been granted.
821     * This optimized lookup structure maps from {@link UriPermission#targetUid}
822     * to {@link UriPermission#uri} to {@link UriPermission}.
823     */
824    @GuardedBy("this")
825    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
826            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
827
828    public static class GrantUri {
829        public final int sourceUserId;
830        public final Uri uri;
831        public boolean prefix;
832
833        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
834            this.sourceUserId = sourceUserId;
835            this.uri = uri;
836            this.prefix = prefix;
837        }
838
839        @Override
840        public int hashCode() {
841            int hashCode = 1;
842            hashCode = 31 * hashCode + sourceUserId;
843            hashCode = 31 * hashCode + uri.hashCode();
844            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
845            return hashCode;
846        }
847
848        @Override
849        public boolean equals(Object o) {
850            if (o instanceof GrantUri) {
851                GrantUri other = (GrantUri) o;
852                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
853                        && prefix == other.prefix;
854            }
855            return false;
856        }
857
858        @Override
859        public String toString() {
860            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
861            if (prefix) result += " [prefix]";
862            return result;
863        }
864
865        public String toSafeString() {
866            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
867            if (prefix) result += " [prefix]";
868            return result;
869        }
870
871        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
872            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
873                    ContentProvider.getUriWithoutUserId(uri), false);
874        }
875    }
876
877    CoreSettingsObserver mCoreSettingsObserver;
878
879    /**
880     * Thread-local storage used to carry caller permissions over through
881     * indirect content-provider access.
882     */
883    private class Identity {
884        public final IBinder token;
885        public final int pid;
886        public final int uid;
887
888        Identity(IBinder _token, int _pid, int _uid) {
889            token = _token;
890            pid = _pid;
891            uid = _uid;
892        }
893    }
894
895    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
896
897    /**
898     * All information we have collected about the runtime performance of
899     * any user id that can impact battery performance.
900     */
901    final BatteryStatsService mBatteryStatsService;
902
903    /**
904     * Information about component usage
905     */
906    UsageStatsManagerInternal mUsageStatsService;
907
908    /**
909     * Information about and control over application operations
910     */
911    final AppOpsService mAppOpsService;
912
913    /**
914     * Save recent tasks information across reboots.
915     */
916    final TaskPersister mTaskPersister;
917
918    /**
919     * Current configuration information.  HistoryRecord objects are given
920     * a reference to this object to indicate which configuration they are
921     * currently running in, so this object must be kept immutable.
922     */
923    Configuration mConfiguration = new Configuration();
924
925    /**
926     * Current sequencing integer of the configuration, for skipping old
927     * configurations.
928     */
929    int mConfigurationSeq = 0;
930
931    /**
932     * Hardware-reported OpenGLES version.
933     */
934    final int GL_ES_VERSION;
935
936    /**
937     * List of initialization arguments to pass to all processes when binding applications to them.
938     * For example, references to the commonly used services.
939     */
940    HashMap<String, IBinder> mAppBindArgs;
941
942    /**
943     * Temporary to avoid allocations.  Protected by main lock.
944     */
945    final StringBuilder mStringBuilder = new StringBuilder(256);
946
947    /**
948     * Used to control how we initialize the service.
949     */
950    ComponentName mTopComponent;
951    String mTopAction = Intent.ACTION_MAIN;
952    String mTopData;
953    boolean mProcessesReady = false;
954    boolean mSystemReady = false;
955    boolean mBooting = false;
956    boolean mCallFinishBooting = false;
957    boolean mBootAnimationComplete = false;
958    boolean mWaitingUpdate = false;
959    boolean mDidUpdate = false;
960    boolean mOnBattery = false;
961    boolean mLaunchWarningShown = false;
962
963    Context mContext;
964
965    int mFactoryTest;
966
967    boolean mCheckedForSetup;
968
969    /**
970     * The time at which we will allow normal application switches again,
971     * after a call to {@link #stopAppSwitches()}.
972     */
973    long mAppSwitchesAllowedTime;
974
975    /**
976     * This is set to true after the first switch after mAppSwitchesAllowedTime
977     * is set; any switches after that will clear the time.
978     */
979    boolean mDidAppSwitch;
980
981    /**
982     * Last time (in realtime) at which we checked for power usage.
983     */
984    long mLastPowerCheckRealtime;
985
986    /**
987     * Last time (in uptime) at which we checked for power usage.
988     */
989    long mLastPowerCheckUptime;
990
991    /**
992     * Set while we are wanting to sleep, to prevent any
993     * activities from being started/resumed.
994     */
995    private boolean mSleeping = false;
996
997    /**
998     * Set while we are running a voice interaction.  This overrides
999     * sleeping while it is active.
1000     */
1001    private boolean mRunningVoice = false;
1002
1003    /**
1004     * State of external calls telling us if the device is awake or asleep.
1005     */
1006    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1007
1008    static final int LOCK_SCREEN_HIDDEN = 0;
1009    static final int LOCK_SCREEN_LEAVING = 1;
1010    static final int LOCK_SCREEN_SHOWN = 2;
1011    /**
1012     * State of external call telling us if the lock screen is shown.
1013     */
1014    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1015
1016    /**
1017     * Set if we are shutting down the system, similar to sleeping.
1018     */
1019    boolean mShuttingDown = false;
1020
1021    /**
1022     * Current sequence id for oom_adj computation traversal.
1023     */
1024    int mAdjSeq = 0;
1025
1026    /**
1027     * Current sequence id for process LRU updating.
1028     */
1029    int mLruSeq = 0;
1030
1031    /**
1032     * Keep track of the non-cached/empty process we last found, to help
1033     * determine how to distribute cached/empty processes next time.
1034     */
1035    int mNumNonCachedProcs = 0;
1036
1037    /**
1038     * Keep track of the number of cached hidden procs, to balance oom adj
1039     * distribution between those and empty procs.
1040     */
1041    int mNumCachedHiddenProcs = 0;
1042
1043    /**
1044     * Keep track of the number of service processes we last found, to
1045     * determine on the next iteration which should be B services.
1046     */
1047    int mNumServiceProcs = 0;
1048    int mNewNumAServiceProcs = 0;
1049    int mNewNumServiceProcs = 0;
1050
1051    /**
1052     * Allow the current computed overall memory level of the system to go down?
1053     * This is set to false when we are killing processes for reasons other than
1054     * memory management, so that the now smaller process list will not be taken as
1055     * an indication that memory is tighter.
1056     */
1057    boolean mAllowLowerMemLevel = false;
1058
1059    /**
1060     * The last computed memory level, for holding when we are in a state that
1061     * processes are going away for other reasons.
1062     */
1063    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1064
1065    /**
1066     * The last total number of process we have, to determine if changes actually look
1067     * like a shrinking number of process due to lower RAM.
1068     */
1069    int mLastNumProcesses;
1070
1071    /**
1072     * The uptime of the last time we performed idle maintenance.
1073     */
1074    long mLastIdleTime = SystemClock.uptimeMillis();
1075
1076    /**
1077     * Total time spent with RAM that has been added in the past since the last idle time.
1078     */
1079    long mLowRamTimeSinceLastIdle = 0;
1080
1081    /**
1082     * If RAM is currently low, when that horrible situation started.
1083     */
1084    long mLowRamStartTime = 0;
1085
1086    /**
1087     * For reporting to battery stats the current top application.
1088     */
1089    private String mCurResumedPackage = null;
1090    private int mCurResumedUid = -1;
1091
1092    /**
1093     * For reporting to battery stats the apps currently running foreground
1094     * service.  The ProcessMap is package/uid tuples; each of these contain
1095     * an array of the currently foreground processes.
1096     */
1097    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1098            = new ProcessMap<ArrayList<ProcessRecord>>();
1099
1100    /**
1101     * This is set if we had to do a delayed dexopt of an app before launching
1102     * it, to increase the ANR timeouts in that case.
1103     */
1104    boolean mDidDexOpt;
1105
1106    /**
1107     * Set if the systemServer made a call to enterSafeMode.
1108     */
1109    boolean mSafeMode;
1110
1111    /**
1112     * If true, we are running under a test environment so will sample PSS from processes
1113     * much more rapidly to try to collect better data when the tests are rapidly
1114     * running through apps.
1115     */
1116    boolean mTestPssMode = false;
1117
1118    String mDebugApp = null;
1119    boolean mWaitForDebugger = false;
1120    boolean mDebugTransient = false;
1121    String mOrigDebugApp = null;
1122    boolean mOrigWaitForDebugger = false;
1123    boolean mAlwaysFinishActivities = false;
1124    IActivityController mController = null;
1125    String mProfileApp = null;
1126    ProcessRecord mProfileProc = null;
1127    String mProfileFile;
1128    ParcelFileDescriptor mProfileFd;
1129    int mSamplingInterval = 0;
1130    boolean mAutoStopProfiler = false;
1131    int mProfileType = 0;
1132    String mOpenGlTraceApp = null;
1133
1134    final long[] mTmpLong = new long[1];
1135
1136    static class ProcessChangeItem {
1137        static final int CHANGE_ACTIVITIES = 1<<0;
1138        static final int CHANGE_PROCESS_STATE = 1<<1;
1139        int changes;
1140        int uid;
1141        int pid;
1142        int processState;
1143        boolean foregroundActivities;
1144    }
1145
1146    final RemoteCallbackList<IProcessObserver> mProcessObservers
1147            = new RemoteCallbackList<IProcessObserver>();
1148    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1149
1150    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1151            = new ArrayList<ProcessChangeItem>();
1152    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1153            = new ArrayList<ProcessChangeItem>();
1154
1155    /**
1156     * Runtime CPU use collection thread.  This object's lock is used to
1157     * perform synchronization with the thread (notifying it to run).
1158     */
1159    final Thread mProcessCpuThread;
1160
1161    /**
1162     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1163     * Must acquire this object's lock when accessing it.
1164     * NOTE: this lock will be held while doing long operations (trawling
1165     * through all processes in /proc), so it should never be acquired by
1166     * any critical paths such as when holding the main activity manager lock.
1167     */
1168    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1169            MONITOR_THREAD_CPU_USAGE);
1170    final AtomicLong mLastCpuTime = new AtomicLong(0);
1171    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1172
1173    long mLastWriteTime = 0;
1174
1175    /**
1176     * Used to retain an update lock when the foreground activity is in
1177     * immersive mode.
1178     */
1179    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1180
1181    /**
1182     * Set to true after the system has finished booting.
1183     */
1184    boolean mBooted = false;
1185
1186    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1187    int mProcessLimitOverride = -1;
1188
1189    WindowManagerService mWindowManager;
1190
1191    final ActivityThread mSystemThread;
1192
1193    // Holds the current foreground user's id
1194    int mCurrentUserId = 0;
1195    // Holds the target user's id during a user switch
1196    int mTargetUserId = UserHandle.USER_NULL;
1197    // If there are multiple profiles for the current user, their ids are here
1198    // Currently only the primary user can have managed profiles
1199    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1200
1201    /**
1202     * Mapping from each known user ID to the profile group ID it is associated with.
1203     */
1204    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1205
1206    private UserManagerService mUserManager;
1207
1208    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1209        final ProcessRecord mApp;
1210        final int mPid;
1211        final IApplicationThread mAppThread;
1212
1213        AppDeathRecipient(ProcessRecord app, int pid,
1214                IApplicationThread thread) {
1215            if (localLOGV) Slog.v(
1216                TAG, "New death recipient " + this
1217                + " for thread " + thread.asBinder());
1218            mApp = app;
1219            mPid = pid;
1220            mAppThread = thread;
1221        }
1222
1223        @Override
1224        public void binderDied() {
1225            if (localLOGV) Slog.v(
1226                TAG, "Death received in " + this
1227                + " for thread " + mAppThread.asBinder());
1228            synchronized(ActivityManagerService.this) {
1229                appDiedLocked(mApp, mPid, mAppThread);
1230            }
1231        }
1232    }
1233
1234    static final int SHOW_ERROR_MSG = 1;
1235    static final int SHOW_NOT_RESPONDING_MSG = 2;
1236    static final int SHOW_FACTORY_ERROR_MSG = 3;
1237    static final int UPDATE_CONFIGURATION_MSG = 4;
1238    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1239    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1240    static final int SERVICE_TIMEOUT_MSG = 12;
1241    static final int UPDATE_TIME_ZONE = 13;
1242    static final int SHOW_UID_ERROR_MSG = 14;
1243    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1244    static final int PROC_START_TIMEOUT_MSG = 20;
1245    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1246    static final int KILL_APPLICATION_MSG = 22;
1247    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1248    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1249    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1250    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1251    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1252    static final int CLEAR_DNS_CACHE_MSG = 28;
1253    static final int UPDATE_HTTP_PROXY_MSG = 29;
1254    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1255    static final int DISPATCH_PROCESSES_CHANGED = 31;
1256    static final int DISPATCH_PROCESS_DIED = 32;
1257    static final int REPORT_MEM_USAGE_MSG = 33;
1258    static final int REPORT_USER_SWITCH_MSG = 34;
1259    static final int CONTINUE_USER_SWITCH_MSG = 35;
1260    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1261    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1262    static final int PERSIST_URI_GRANTS_MSG = 38;
1263    static final int REQUEST_ALL_PSS_MSG = 39;
1264    static final int START_PROFILES_MSG = 40;
1265    static final int UPDATE_TIME = 41;
1266    static final int SYSTEM_USER_START_MSG = 42;
1267    static final int SYSTEM_USER_CURRENT_MSG = 43;
1268    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1269    static final int FINISH_BOOTING_MSG = 45;
1270    static final int START_USER_SWITCH_MSG = 46;
1271    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1272    static final int DISMISS_DIALOG_MSG = 48;
1273    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1274
1275    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1276    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1277    static final int FIRST_COMPAT_MODE_MSG = 300;
1278    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1279
1280    CompatModeDialog mCompatModeDialog;
1281    long mLastMemUsageReportTime = 0;
1282
1283    /**
1284     * Flag whether the current user is a "monkey", i.e. whether
1285     * the UI is driven by a UI automation tool.
1286     */
1287    private boolean mUserIsMonkey;
1288
1289    /** Flag whether the device has a Recents UI */
1290    boolean mHasRecents;
1291
1292    /** The dimensions of the thumbnails in the Recents UI. */
1293    int mThumbnailWidth;
1294    int mThumbnailHeight;
1295
1296    final ServiceThread mHandlerThread;
1297    final MainHandler mHandler;
1298
1299    final class MainHandler extends Handler {
1300        public MainHandler(Looper looper) {
1301            super(looper, null, true);
1302        }
1303
1304        @Override
1305        public void handleMessage(Message msg) {
1306            switch (msg.what) {
1307            case SHOW_ERROR_MSG: {
1308                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1309                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1310                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1311                synchronized (ActivityManagerService.this) {
1312                    ProcessRecord proc = (ProcessRecord)data.get("app");
1313                    AppErrorResult res = (AppErrorResult) data.get("result");
1314                    if (proc != null && proc.crashDialog != null) {
1315                        Slog.e(TAG, "App already has crash dialog: " + proc);
1316                        if (res != null) {
1317                            res.set(0);
1318                        }
1319                        return;
1320                    }
1321                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1322                            >= Process.FIRST_APPLICATION_UID
1323                            && proc.pid != MY_PID);
1324                    for (int userId : mCurrentProfileIds) {
1325                        isBackground &= (proc.userId != userId);
1326                    }
1327                    if (isBackground && !showBackground) {
1328                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1329                        if (res != null) {
1330                            res.set(0);
1331                        }
1332                        return;
1333                    }
1334                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1335                        Dialog d = new AppErrorDialog(mContext,
1336                                ActivityManagerService.this, res, proc);
1337                        d.show();
1338                        proc.crashDialog = d;
1339                    } else {
1340                        // The device is asleep, so just pretend that the user
1341                        // saw a crash dialog and hit "force quit".
1342                        if (res != null) {
1343                            res.set(0);
1344                        }
1345                    }
1346                }
1347
1348                ensureBootCompleted();
1349            } break;
1350            case SHOW_NOT_RESPONDING_MSG: {
1351                synchronized (ActivityManagerService.this) {
1352                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1353                    ProcessRecord proc = (ProcessRecord)data.get("app");
1354                    if (proc != null && proc.anrDialog != null) {
1355                        Slog.e(TAG, "App already has anr dialog: " + proc);
1356                        return;
1357                    }
1358
1359                    Intent intent = new Intent("android.intent.action.ANR");
1360                    if (!mProcessesReady) {
1361                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1362                                | Intent.FLAG_RECEIVER_FOREGROUND);
1363                    }
1364                    broadcastIntentLocked(null, null, intent,
1365                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1366                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1367
1368                    if (mShowDialogs) {
1369                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1370                                mContext, proc, (ActivityRecord)data.get("activity"),
1371                                msg.arg1 != 0);
1372                        d.show();
1373                        proc.anrDialog = d;
1374                    } else {
1375                        // Just kill the app if there is no dialog to be shown.
1376                        killAppAtUsersRequest(proc, null);
1377                    }
1378                }
1379
1380                ensureBootCompleted();
1381            } break;
1382            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1383                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1384                synchronized (ActivityManagerService.this) {
1385                    ProcessRecord proc = (ProcessRecord) data.get("app");
1386                    if (proc == null) {
1387                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1388                        break;
1389                    }
1390                    if (proc.crashDialog != null) {
1391                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1392                        return;
1393                    }
1394                    AppErrorResult res = (AppErrorResult) data.get("result");
1395                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1396                        Dialog d = new StrictModeViolationDialog(mContext,
1397                                ActivityManagerService.this, res, proc);
1398                        d.show();
1399                        proc.crashDialog = d;
1400                    } else {
1401                        // The device is asleep, so just pretend that the user
1402                        // saw a crash dialog and hit "force quit".
1403                        res.set(0);
1404                    }
1405                }
1406                ensureBootCompleted();
1407            } break;
1408            case SHOW_FACTORY_ERROR_MSG: {
1409                Dialog d = new FactoryErrorDialog(
1410                    mContext, msg.getData().getCharSequence("msg"));
1411                d.show();
1412                ensureBootCompleted();
1413            } break;
1414            case UPDATE_CONFIGURATION_MSG: {
1415                final ContentResolver resolver = mContext.getContentResolver();
1416                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1417            } break;
1418            case GC_BACKGROUND_PROCESSES_MSG: {
1419                synchronized (ActivityManagerService.this) {
1420                    performAppGcsIfAppropriateLocked();
1421                }
1422            } break;
1423            case WAIT_FOR_DEBUGGER_MSG: {
1424                synchronized (ActivityManagerService.this) {
1425                    ProcessRecord app = (ProcessRecord)msg.obj;
1426                    if (msg.arg1 != 0) {
1427                        if (!app.waitedForDebugger) {
1428                            Dialog d = new AppWaitingForDebuggerDialog(
1429                                    ActivityManagerService.this,
1430                                    mContext, app);
1431                            app.waitDialog = d;
1432                            app.waitedForDebugger = true;
1433                            d.show();
1434                        }
1435                    } else {
1436                        if (app.waitDialog != null) {
1437                            app.waitDialog.dismiss();
1438                            app.waitDialog = null;
1439                        }
1440                    }
1441                }
1442            } break;
1443            case SERVICE_TIMEOUT_MSG: {
1444                if (mDidDexOpt) {
1445                    mDidDexOpt = false;
1446                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1447                    nmsg.obj = msg.obj;
1448                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1449                    return;
1450                }
1451                mServices.serviceTimeout((ProcessRecord)msg.obj);
1452            } break;
1453            case UPDATE_TIME_ZONE: {
1454                synchronized (ActivityManagerService.this) {
1455                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1456                        ProcessRecord r = mLruProcesses.get(i);
1457                        if (r.thread != null) {
1458                            try {
1459                                r.thread.updateTimeZone();
1460                            } catch (RemoteException ex) {
1461                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1462                            }
1463                        }
1464                    }
1465                }
1466            } break;
1467            case CLEAR_DNS_CACHE_MSG: {
1468                synchronized (ActivityManagerService.this) {
1469                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1470                        ProcessRecord r = mLruProcesses.get(i);
1471                        if (r.thread != null) {
1472                            try {
1473                                r.thread.clearDnsCache();
1474                            } catch (RemoteException ex) {
1475                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1476                            }
1477                        }
1478                    }
1479                }
1480            } break;
1481            case UPDATE_HTTP_PROXY_MSG: {
1482                ProxyInfo proxy = (ProxyInfo)msg.obj;
1483                String host = "";
1484                String port = "";
1485                String exclList = "";
1486                Uri pacFileUrl = Uri.EMPTY;
1487                if (proxy != null) {
1488                    host = proxy.getHost();
1489                    port = Integer.toString(proxy.getPort());
1490                    exclList = proxy.getExclusionListAsString();
1491                    pacFileUrl = proxy.getPacFileUrl();
1492                }
1493                synchronized (ActivityManagerService.this) {
1494                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1495                        ProcessRecord r = mLruProcesses.get(i);
1496                        if (r.thread != null) {
1497                            try {
1498                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1499                            } catch (RemoteException ex) {
1500                                Slog.w(TAG, "Failed to update http proxy for: " +
1501                                        r.info.processName);
1502                            }
1503                        }
1504                    }
1505                }
1506            } break;
1507            case SHOW_UID_ERROR_MSG: {
1508                if (mShowDialogs) {
1509                    AlertDialog d = new BaseErrorDialog(mContext);
1510                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1511                    d.setCancelable(false);
1512                    d.setTitle(mContext.getText(R.string.android_system_label));
1513                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1514                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1515                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1516                    d.show();
1517                }
1518            } break;
1519            case SHOW_FINGERPRINT_ERROR_MSG: {
1520                if (mShowDialogs) {
1521                    AlertDialog d = new BaseErrorDialog(mContext);
1522                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1523                    d.setCancelable(false);
1524                    d.setTitle(mContext.getText(R.string.android_system_label));
1525                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1526                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1527                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1528                    d.show();
1529                }
1530            } break;
1531            case PROC_START_TIMEOUT_MSG: {
1532                if (mDidDexOpt) {
1533                    mDidDexOpt = false;
1534                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1535                    nmsg.obj = msg.obj;
1536                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1537                    return;
1538                }
1539                ProcessRecord app = (ProcessRecord)msg.obj;
1540                synchronized (ActivityManagerService.this) {
1541                    processStartTimedOutLocked(app);
1542                }
1543            } break;
1544            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1545                synchronized (ActivityManagerService.this) {
1546                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1547                }
1548            } break;
1549            case KILL_APPLICATION_MSG: {
1550                synchronized (ActivityManagerService.this) {
1551                    int appid = msg.arg1;
1552                    boolean restart = (msg.arg2 == 1);
1553                    Bundle bundle = (Bundle)msg.obj;
1554                    String pkg = bundle.getString("pkg");
1555                    String reason = bundle.getString("reason");
1556                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1557                            false, UserHandle.USER_ALL, reason);
1558                }
1559            } break;
1560            case FINALIZE_PENDING_INTENT_MSG: {
1561                ((PendingIntentRecord)msg.obj).completeFinalize();
1562            } break;
1563            case POST_HEAVY_NOTIFICATION_MSG: {
1564                INotificationManager inm = NotificationManager.getService();
1565                if (inm == null) {
1566                    return;
1567                }
1568
1569                ActivityRecord root = (ActivityRecord)msg.obj;
1570                ProcessRecord process = root.app;
1571                if (process == null) {
1572                    return;
1573                }
1574
1575                try {
1576                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1577                    String text = mContext.getString(R.string.heavy_weight_notification,
1578                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1579                    Notification notification = new Notification();
1580                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1581                    notification.when = 0;
1582                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1583                    notification.tickerText = text;
1584                    notification.defaults = 0; // please be quiet
1585                    notification.sound = null;
1586                    notification.vibrate = null;
1587                    notification.color = mContext.getResources().getColor(
1588                            com.android.internal.R.color.system_notification_accent_color);
1589                    notification.setLatestEventInfo(context, text,
1590                            mContext.getText(R.string.heavy_weight_notification_detail),
1591                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1592                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1593                                    new UserHandle(root.userId)));
1594
1595                    try {
1596                        int[] outId = new int[1];
1597                        inm.enqueueNotificationWithTag("android", "android", null,
1598                                R.string.heavy_weight_notification,
1599                                notification, outId, root.userId);
1600                    } catch (RuntimeException e) {
1601                        Slog.w(ActivityManagerService.TAG,
1602                                "Error showing notification for heavy-weight app", e);
1603                    } catch (RemoteException e) {
1604                    }
1605                } catch (NameNotFoundException e) {
1606                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1607                }
1608            } break;
1609            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1610                INotificationManager inm = NotificationManager.getService();
1611                if (inm == null) {
1612                    return;
1613                }
1614                try {
1615                    inm.cancelNotificationWithTag("android", null,
1616                            R.string.heavy_weight_notification,  msg.arg1);
1617                } catch (RuntimeException e) {
1618                    Slog.w(ActivityManagerService.TAG,
1619                            "Error canceling notification for service", e);
1620                } catch (RemoteException e) {
1621                }
1622            } break;
1623            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1624                synchronized (ActivityManagerService.this) {
1625                    checkExcessivePowerUsageLocked(true);
1626                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1627                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1628                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1629                }
1630            } break;
1631            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1632                synchronized (ActivityManagerService.this) {
1633                    ActivityRecord ar = (ActivityRecord)msg.obj;
1634                    if (mCompatModeDialog != null) {
1635                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1636                                ar.info.applicationInfo.packageName)) {
1637                            return;
1638                        }
1639                        mCompatModeDialog.dismiss();
1640                        mCompatModeDialog = null;
1641                    }
1642                    if (ar != null && false) {
1643                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1644                                ar.packageName)) {
1645                            int mode = mCompatModePackages.computeCompatModeLocked(
1646                                    ar.info.applicationInfo);
1647                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1648                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1649                                mCompatModeDialog = new CompatModeDialog(
1650                                        ActivityManagerService.this, mContext,
1651                                        ar.info.applicationInfo);
1652                                mCompatModeDialog.show();
1653                            }
1654                        }
1655                    }
1656                }
1657                break;
1658            }
1659            case DISPATCH_PROCESSES_CHANGED: {
1660                dispatchProcessesChanged();
1661                break;
1662            }
1663            case DISPATCH_PROCESS_DIED: {
1664                final int pid = msg.arg1;
1665                final int uid = msg.arg2;
1666                dispatchProcessDied(pid, uid);
1667                break;
1668            }
1669            case REPORT_MEM_USAGE_MSG: {
1670                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1671                Thread thread = new Thread() {
1672                    @Override public void run() {
1673                        reportMemUsage(memInfos);
1674                    }
1675                };
1676                thread.start();
1677                break;
1678            }
1679            case START_USER_SWITCH_MSG: {
1680                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1681                break;
1682            }
1683            case REPORT_USER_SWITCH_MSG: {
1684                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1685                break;
1686            }
1687            case CONTINUE_USER_SWITCH_MSG: {
1688                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1689                break;
1690            }
1691            case USER_SWITCH_TIMEOUT_MSG: {
1692                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1693                break;
1694            }
1695            case IMMERSIVE_MODE_LOCK_MSG: {
1696                final boolean nextState = (msg.arg1 != 0);
1697                if (mUpdateLock.isHeld() != nextState) {
1698                    if (DEBUG_IMMERSIVE) {
1699                        final ActivityRecord r = (ActivityRecord) msg.obj;
1700                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1701                    }
1702                    if (nextState) {
1703                        mUpdateLock.acquire();
1704                    } else {
1705                        mUpdateLock.release();
1706                    }
1707                }
1708                break;
1709            }
1710            case PERSIST_URI_GRANTS_MSG: {
1711                writeGrantedUriPermissions();
1712                break;
1713            }
1714            case REQUEST_ALL_PSS_MSG: {
1715                synchronized (ActivityManagerService.this) {
1716                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1717                }
1718                break;
1719            }
1720            case START_PROFILES_MSG: {
1721                synchronized (ActivityManagerService.this) {
1722                    startProfilesLocked();
1723                }
1724                break;
1725            }
1726            case UPDATE_TIME: {
1727                synchronized (ActivityManagerService.this) {
1728                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1729                        ProcessRecord r = mLruProcesses.get(i);
1730                        if (r.thread != null) {
1731                            try {
1732                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1733                            } catch (RemoteException ex) {
1734                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1735                            }
1736                        }
1737                    }
1738                }
1739                break;
1740            }
1741            case SYSTEM_USER_START_MSG: {
1742                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1743                        Integer.toString(msg.arg1), msg.arg1);
1744                mSystemServiceManager.startUser(msg.arg1);
1745                break;
1746            }
1747            case SYSTEM_USER_CURRENT_MSG: {
1748                mBatteryStatsService.noteEvent(
1749                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1750                        Integer.toString(msg.arg2), msg.arg2);
1751                mBatteryStatsService.noteEvent(
1752                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1753                        Integer.toString(msg.arg1), msg.arg1);
1754                mSystemServiceManager.switchUser(msg.arg1);
1755                break;
1756            }
1757            case ENTER_ANIMATION_COMPLETE_MSG: {
1758                synchronized (ActivityManagerService.this) {
1759                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1760                    if (r != null && r.app != null && r.app.thread != null) {
1761                        try {
1762                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1763                        } catch (RemoteException e) {
1764                        }
1765                    }
1766                }
1767                break;
1768            }
1769            case FINISH_BOOTING_MSG: {
1770                if (msg.arg1 != 0) {
1771                    finishBooting();
1772                }
1773                if (msg.arg2 != 0) {
1774                    enableScreenAfterBoot();
1775                }
1776                break;
1777            }
1778            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1779                try {
1780                    Locale l = (Locale) msg.obj;
1781                    IBinder service = ServiceManager.getService("mount");
1782                    IMountService mountService = IMountService.Stub.asInterface(service);
1783                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1784                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1785                } catch (RemoteException e) {
1786                    Log.e(TAG, "Error storing locale for decryption UI", e);
1787                }
1788                break;
1789            }
1790            case DISMISS_DIALOG_MSG: {
1791                final Dialog d = (Dialog) msg.obj;
1792                d.dismiss();
1793                break;
1794            }
1795            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1796                synchronized (ActivityManagerService.this) {
1797                    int i = mTaskStackListeners.beginBroadcast();
1798                    while (i > 0) {
1799                        i--;
1800                        try {
1801                            // Make a one-way callback to the listener
1802                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1803                        } catch (RemoteException e){
1804                            // Handled by the RemoteCallbackList
1805                        }
1806                    }
1807                    mTaskStackListeners.finishBroadcast();
1808                }
1809                break;
1810            }
1811            }
1812        }
1813    };
1814
1815    static final int COLLECT_PSS_BG_MSG = 1;
1816
1817    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1818        @Override
1819        public void handleMessage(Message msg) {
1820            switch (msg.what) {
1821            case COLLECT_PSS_BG_MSG: {
1822                long start = SystemClock.uptimeMillis();
1823                MemInfoReader memInfo = null;
1824                synchronized (ActivityManagerService.this) {
1825                    if (mFullPssPending) {
1826                        mFullPssPending = false;
1827                        memInfo = new MemInfoReader();
1828                    }
1829                }
1830                if (memInfo != null) {
1831                    updateCpuStatsNow();
1832                    long nativeTotalPss = 0;
1833                    synchronized (mProcessCpuTracker) {
1834                        final int N = mProcessCpuTracker.countStats();
1835                        for (int j=0; j<N; j++) {
1836                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1837                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1838                                // This is definitely an application process; skip it.
1839                                continue;
1840                            }
1841                            synchronized (mPidsSelfLocked) {
1842                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1843                                    // This is one of our own processes; skip it.
1844                                    continue;
1845                                }
1846                            }
1847                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1848                        }
1849                    }
1850                    memInfo.readMemInfo();
1851                    synchronized (ActivityManagerService.this) {
1852                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1853                                + (SystemClock.uptimeMillis()-start) + "ms");
1854                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1855                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1856                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1857                    }
1858                }
1859
1860                int num = 0;
1861                long[] tmp = new long[1];
1862                do {
1863                    ProcessRecord proc;
1864                    int procState;
1865                    int pid;
1866                    long lastPssTime;
1867                    synchronized (ActivityManagerService.this) {
1868                        if (mPendingPssProcesses.size() <= 0) {
1869                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1870                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1871                            mPendingPssProcesses.clear();
1872                            return;
1873                        }
1874                        proc = mPendingPssProcesses.remove(0);
1875                        procState = proc.pssProcState;
1876                        lastPssTime = proc.lastPssTime;
1877                        if (proc.thread != null && procState == proc.setProcState
1878                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1879                                        < SystemClock.uptimeMillis()) {
1880                            pid = proc.pid;
1881                        } else {
1882                            proc = null;
1883                            pid = 0;
1884                        }
1885                    }
1886                    if (proc != null) {
1887                        long pss = Debug.getPss(pid, tmp, null);
1888                        synchronized (ActivityManagerService.this) {
1889                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1890                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1891                                num++;
1892                                recordPssSample(proc, procState, pss, tmp[0],
1893                                        SystemClock.uptimeMillis());
1894                            }
1895                        }
1896                    }
1897                } while (true);
1898            }
1899            }
1900        }
1901    };
1902
1903    public void setSystemProcess() {
1904        try {
1905            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1906            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1907            ServiceManager.addService("meminfo", new MemBinder(this));
1908            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1909            ServiceManager.addService("dbinfo", new DbBinder(this));
1910            if (MONITOR_CPU_USAGE) {
1911                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1912            }
1913            ServiceManager.addService("permission", new PermissionController(this));
1914
1915            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1916                    "android", STOCK_PM_FLAGS);
1917            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1918
1919            synchronized (this) {
1920                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1921                app.persistent = true;
1922                app.pid = MY_PID;
1923                app.maxAdj = ProcessList.SYSTEM_ADJ;
1924                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1925                mProcessNames.put(app.processName, app.uid, app);
1926                synchronized (mPidsSelfLocked) {
1927                    mPidsSelfLocked.put(app.pid, app);
1928                }
1929                updateLruProcessLocked(app, false, null);
1930                updateOomAdjLocked();
1931            }
1932        } catch (PackageManager.NameNotFoundException e) {
1933            throw new RuntimeException(
1934                    "Unable to find android system package", e);
1935        }
1936    }
1937
1938    public void setWindowManager(WindowManagerService wm) {
1939        mWindowManager = wm;
1940        mStackSupervisor.setWindowManager(wm);
1941    }
1942
1943    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1944        mUsageStatsService = usageStatsManager;
1945    }
1946
1947    public void startObservingNativeCrashes() {
1948        final NativeCrashListener ncl = new NativeCrashListener(this);
1949        ncl.start();
1950    }
1951
1952    public IAppOpsService getAppOpsService() {
1953        return mAppOpsService;
1954    }
1955
1956    static class MemBinder extends Binder {
1957        ActivityManagerService mActivityManagerService;
1958        MemBinder(ActivityManagerService activityManagerService) {
1959            mActivityManagerService = activityManagerService;
1960        }
1961
1962        @Override
1963        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1964            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1965                    != PackageManager.PERMISSION_GRANTED) {
1966                pw.println("Permission Denial: can't dump meminfo from from pid="
1967                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1968                        + " without permission " + android.Manifest.permission.DUMP);
1969                return;
1970            }
1971
1972            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1973        }
1974    }
1975
1976    static class GraphicsBinder extends Binder {
1977        ActivityManagerService mActivityManagerService;
1978        GraphicsBinder(ActivityManagerService activityManagerService) {
1979            mActivityManagerService = activityManagerService;
1980        }
1981
1982        @Override
1983        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1984            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1985                    != PackageManager.PERMISSION_GRANTED) {
1986                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1987                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1988                        + " without permission " + android.Manifest.permission.DUMP);
1989                return;
1990            }
1991
1992            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1993        }
1994    }
1995
1996    static class DbBinder extends Binder {
1997        ActivityManagerService mActivityManagerService;
1998        DbBinder(ActivityManagerService activityManagerService) {
1999            mActivityManagerService = activityManagerService;
2000        }
2001
2002        @Override
2003        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2004            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2005                    != PackageManager.PERMISSION_GRANTED) {
2006                pw.println("Permission Denial: can't dump dbinfo from from pid="
2007                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2008                        + " without permission " + android.Manifest.permission.DUMP);
2009                return;
2010            }
2011
2012            mActivityManagerService.dumpDbInfo(fd, pw, args);
2013        }
2014    }
2015
2016    static class CpuBinder extends Binder {
2017        ActivityManagerService mActivityManagerService;
2018        CpuBinder(ActivityManagerService activityManagerService) {
2019            mActivityManagerService = activityManagerService;
2020        }
2021
2022        @Override
2023        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2024            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2025                    != PackageManager.PERMISSION_GRANTED) {
2026                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2027                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2028                        + " without permission " + android.Manifest.permission.DUMP);
2029                return;
2030            }
2031
2032            synchronized (mActivityManagerService.mProcessCpuTracker) {
2033                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2034                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2035                        SystemClock.uptimeMillis()));
2036            }
2037        }
2038    }
2039
2040    public static final class Lifecycle extends SystemService {
2041        private final ActivityManagerService mService;
2042
2043        public Lifecycle(Context context) {
2044            super(context);
2045            mService = new ActivityManagerService(context);
2046        }
2047
2048        @Override
2049        public void onStart() {
2050            mService.start();
2051        }
2052
2053        public ActivityManagerService getService() {
2054            return mService;
2055        }
2056    }
2057
2058    // Note: This method is invoked on the main thread but may need to attach various
2059    // handlers to other threads.  So take care to be explicit about the looper.
2060    public ActivityManagerService(Context systemContext) {
2061        mContext = systemContext;
2062        mFactoryTest = FactoryTest.getMode();
2063        mSystemThread = ActivityThread.currentActivityThread();
2064
2065        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2066
2067        mHandlerThread = new ServiceThread(TAG,
2068                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2069        mHandlerThread.start();
2070        mHandler = new MainHandler(mHandlerThread.getLooper());
2071
2072        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2073                "foreground", BROADCAST_FG_TIMEOUT, false);
2074        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2075                "background", BROADCAST_BG_TIMEOUT, true);
2076        mBroadcastQueues[0] = mFgBroadcastQueue;
2077        mBroadcastQueues[1] = mBgBroadcastQueue;
2078
2079        mServices = new ActiveServices(this);
2080        mProviderMap = new ProviderMap(this);
2081
2082        // TODO: Move creation of battery stats service outside of activity manager service.
2083        File dataDir = Environment.getDataDirectory();
2084        File systemDir = new File(dataDir, "system");
2085        systemDir.mkdirs();
2086        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2087        mBatteryStatsService.getActiveStatistics().readLocked();
2088        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2089        mOnBattery = DEBUG_POWER ? true
2090                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2091        mBatteryStatsService.getActiveStatistics().setCallback(this);
2092
2093        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2094
2095        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2096
2097        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2098
2099        // User 0 is the first and only user that runs at boot.
2100        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2101        mUserLru.add(Integer.valueOf(0));
2102        updateStartedUserArrayLocked();
2103
2104        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2105            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2106
2107        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2108
2109        mConfiguration.setToDefaults();
2110        mConfiguration.locale = Locale.getDefault();
2111
2112        mConfigurationSeq = mConfiguration.seq = 1;
2113        mProcessCpuTracker.init();
2114
2115        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2116        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2117        mStackSupervisor = new ActivityStackSupervisor(this);
2118        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2119
2120        mProcessCpuThread = new Thread("CpuTracker") {
2121            @Override
2122            public void run() {
2123                while (true) {
2124                    try {
2125                        try {
2126                            synchronized(this) {
2127                                final long now = SystemClock.uptimeMillis();
2128                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2129                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2130                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2131                                //        + ", write delay=" + nextWriteDelay);
2132                                if (nextWriteDelay < nextCpuDelay) {
2133                                    nextCpuDelay = nextWriteDelay;
2134                                }
2135                                if (nextCpuDelay > 0) {
2136                                    mProcessCpuMutexFree.set(true);
2137                                    this.wait(nextCpuDelay);
2138                                }
2139                            }
2140                        } catch (InterruptedException e) {
2141                        }
2142                        updateCpuStatsNow();
2143                    } catch (Exception e) {
2144                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2145                    }
2146                }
2147            }
2148        };
2149
2150        Watchdog.getInstance().addMonitor(this);
2151        Watchdog.getInstance().addThread(mHandler);
2152    }
2153
2154    public void setSystemServiceManager(SystemServiceManager mgr) {
2155        mSystemServiceManager = mgr;
2156    }
2157
2158    public void setInstaller(Installer installer) {
2159        mInstaller = installer;
2160    }
2161
2162    private void start() {
2163        Process.removeAllProcessGroups();
2164        mProcessCpuThread.start();
2165
2166        mBatteryStatsService.publish(mContext);
2167        mAppOpsService.publish(mContext);
2168        Slog.d("AppOps", "AppOpsService published");
2169        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2170    }
2171
2172    public void initPowerManagement() {
2173        mStackSupervisor.initPowerManagement();
2174        mBatteryStatsService.initPowerManagement();
2175    }
2176
2177    @Override
2178    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2179            throws RemoteException {
2180        if (code == SYSPROPS_TRANSACTION) {
2181            // We need to tell all apps about the system property change.
2182            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2183            synchronized(this) {
2184                final int NP = mProcessNames.getMap().size();
2185                for (int ip=0; ip<NP; ip++) {
2186                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2187                    final int NA = apps.size();
2188                    for (int ia=0; ia<NA; ia++) {
2189                        ProcessRecord app = apps.valueAt(ia);
2190                        if (app.thread != null) {
2191                            procs.add(app.thread.asBinder());
2192                        }
2193                    }
2194                }
2195            }
2196
2197            int N = procs.size();
2198            for (int i=0; i<N; i++) {
2199                Parcel data2 = Parcel.obtain();
2200                try {
2201                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2202                } catch (RemoteException e) {
2203                }
2204                data2.recycle();
2205            }
2206        }
2207        try {
2208            return super.onTransact(code, data, reply, flags);
2209        } catch (RuntimeException e) {
2210            // The activity manager only throws security exceptions, so let's
2211            // log all others.
2212            if (!(e instanceof SecurityException)) {
2213                Slog.wtf(TAG, "Activity Manager Crash", e);
2214            }
2215            throw e;
2216        }
2217    }
2218
2219    void updateCpuStats() {
2220        final long now = SystemClock.uptimeMillis();
2221        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2222            return;
2223        }
2224        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2225            synchronized (mProcessCpuThread) {
2226                mProcessCpuThread.notify();
2227            }
2228        }
2229    }
2230
2231    void updateCpuStatsNow() {
2232        synchronized (mProcessCpuTracker) {
2233            mProcessCpuMutexFree.set(false);
2234            final long now = SystemClock.uptimeMillis();
2235            boolean haveNewCpuStats = false;
2236
2237            if (MONITOR_CPU_USAGE &&
2238                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2239                mLastCpuTime.set(now);
2240                haveNewCpuStats = true;
2241                mProcessCpuTracker.update();
2242                //Slog.i(TAG, mProcessCpu.printCurrentState());
2243                //Slog.i(TAG, "Total CPU usage: "
2244                //        + mProcessCpu.getTotalCpuPercent() + "%");
2245
2246                // Slog the cpu usage if the property is set.
2247                if ("true".equals(SystemProperties.get("events.cpu"))) {
2248                    int user = mProcessCpuTracker.getLastUserTime();
2249                    int system = mProcessCpuTracker.getLastSystemTime();
2250                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2251                    int irq = mProcessCpuTracker.getLastIrqTime();
2252                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2253                    int idle = mProcessCpuTracker.getLastIdleTime();
2254
2255                    int total = user + system + iowait + irq + softIrq + idle;
2256                    if (total == 0) total = 1;
2257
2258                    EventLog.writeEvent(EventLogTags.CPU,
2259                            ((user+system+iowait+irq+softIrq) * 100) / total,
2260                            (user * 100) / total,
2261                            (system * 100) / total,
2262                            (iowait * 100) / total,
2263                            (irq * 100) / total,
2264                            (softIrq * 100) / total);
2265                }
2266            }
2267
2268            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2269            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2270            synchronized(bstats) {
2271                synchronized(mPidsSelfLocked) {
2272                    if (haveNewCpuStats) {
2273                        if (mOnBattery) {
2274                            int perc = bstats.startAddingCpuLocked();
2275                            int totalUTime = 0;
2276                            int totalSTime = 0;
2277                            final int N = mProcessCpuTracker.countStats();
2278                            for (int i=0; i<N; i++) {
2279                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2280                                if (!st.working) {
2281                                    continue;
2282                                }
2283                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2284                                int otherUTime = (st.rel_utime*perc)/100;
2285                                int otherSTime = (st.rel_stime*perc)/100;
2286                                totalUTime += otherUTime;
2287                                totalSTime += otherSTime;
2288                                if (pr != null) {
2289                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2290                                    if (ps == null || !ps.isActive()) {
2291                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2292                                                pr.info.uid, pr.processName);
2293                                    }
2294                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2295                                            st.rel_stime-otherSTime);
2296                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2297                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2298                                } else {
2299                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2300                                    if (ps == null || !ps.isActive()) {
2301                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2302                                                bstats.mapUid(st.uid), st.name);
2303                                    }
2304                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2305                                            st.rel_stime-otherSTime);
2306                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2307                                }
2308                            }
2309                            bstats.finishAddingCpuLocked(perc, totalUTime,
2310                                    totalSTime, cpuSpeedTimes);
2311                        }
2312                    }
2313                }
2314
2315                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2316                    mLastWriteTime = now;
2317                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2318                }
2319            }
2320        }
2321    }
2322
2323    @Override
2324    public void batteryNeedsCpuUpdate() {
2325        updateCpuStatsNow();
2326    }
2327
2328    @Override
2329    public void batteryPowerChanged(boolean onBattery) {
2330        // When plugging in, update the CPU stats first before changing
2331        // the plug state.
2332        updateCpuStatsNow();
2333        synchronized (this) {
2334            synchronized(mPidsSelfLocked) {
2335                mOnBattery = DEBUG_POWER ? true : onBattery;
2336            }
2337        }
2338    }
2339
2340    /**
2341     * Initialize the application bind args. These are passed to each
2342     * process when the bindApplication() IPC is sent to the process. They're
2343     * lazily setup to make sure the services are running when they're asked for.
2344     */
2345    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2346        if (mAppBindArgs == null) {
2347            mAppBindArgs = new HashMap<>();
2348
2349            // Isolated processes won't get this optimization, so that we don't
2350            // violate the rules about which services they have access to.
2351            if (!isolated) {
2352                // Setup the application init args
2353                mAppBindArgs.put("package", ServiceManager.getService("package"));
2354                mAppBindArgs.put("window", ServiceManager.getService("window"));
2355                mAppBindArgs.put(Context.ALARM_SERVICE,
2356                        ServiceManager.getService(Context.ALARM_SERVICE));
2357            }
2358        }
2359        return mAppBindArgs;
2360    }
2361
2362    final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2363        if (mFocusedActivity != r) {
2364            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2365            mFocusedActivity = r;
2366            if (r.task != null && r.task.voiceInteractor != null) {
2367                startRunningVoiceLocked();
2368            } else {
2369                finishRunningVoiceLocked();
2370            }
2371            mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity");
2372            if (r != null) {
2373                mWindowManager.setFocusedApp(r.appToken, true);
2374            }
2375            applyUpdateLockStateLocked(r);
2376        }
2377        EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
2378                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2379    }
2380
2381    final void clearFocusedActivity(ActivityRecord r) {
2382        if (mFocusedActivity == r) {
2383            mFocusedActivity = null;
2384        }
2385    }
2386
2387    @Override
2388    public void setFocusedStack(int stackId) {
2389        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2390        synchronized (ActivityManagerService.this) {
2391            ActivityStack stack = mStackSupervisor.getStack(stackId);
2392            if (stack != null) {
2393                ActivityRecord r = stack.topRunningActivityLocked(null);
2394                if (r != null) {
2395                    setFocusedActivityLocked(r, "setFocusedStack");
2396                }
2397            }
2398        }
2399    }
2400
2401    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2402    @Override
2403    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2404        synchronized (ActivityManagerService.this) {
2405            if (listener != null) {
2406                mTaskStackListeners.register(listener);
2407            }
2408        }
2409    }
2410
2411    @Override
2412    public void notifyActivityDrawn(IBinder token) {
2413        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2414        synchronized (this) {
2415            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2416            if (r != null) {
2417                r.task.stack.notifyActivityDrawnLocked(r);
2418            }
2419        }
2420    }
2421
2422    final void applyUpdateLockStateLocked(ActivityRecord r) {
2423        // Modifications to the UpdateLock state are done on our handler, outside
2424        // the activity manager's locks.  The new state is determined based on the
2425        // state *now* of the relevant activity record.  The object is passed to
2426        // the handler solely for logging detail, not to be consulted/modified.
2427        final boolean nextState = r != null && r.immersive;
2428        mHandler.sendMessage(
2429                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2430    }
2431
2432    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2433        Message msg = Message.obtain();
2434        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2435        msg.obj = r.task.askedCompatMode ? null : r;
2436        mHandler.sendMessage(msg);
2437    }
2438
2439    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2440            String what, Object obj, ProcessRecord srcApp) {
2441        app.lastActivityTime = now;
2442
2443        if (app.activities.size() > 0) {
2444            // Don't want to touch dependent processes that are hosting activities.
2445            return index;
2446        }
2447
2448        int lrui = mLruProcesses.lastIndexOf(app);
2449        if (lrui < 0) {
2450            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2451                    + what + " " + obj + " from " + srcApp);
2452            return index;
2453        }
2454
2455        if (lrui >= index) {
2456            // Don't want to cause this to move dependent processes *back* in the
2457            // list as if they were less frequently used.
2458            return index;
2459        }
2460
2461        if (lrui >= mLruProcessActivityStart) {
2462            // Don't want to touch dependent processes that are hosting activities.
2463            return index;
2464        }
2465
2466        mLruProcesses.remove(lrui);
2467        if (index > 0) {
2468            index--;
2469        }
2470        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2471                + " in LRU list: " + app);
2472        mLruProcesses.add(index, app);
2473        return index;
2474    }
2475
2476    final void removeLruProcessLocked(ProcessRecord app) {
2477        int lrui = mLruProcesses.lastIndexOf(app);
2478        if (lrui >= 0) {
2479            if (!app.killed) {
2480                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2481                Process.killProcessQuiet(app.pid);
2482                Process.killProcessGroup(app.info.uid, app.pid);
2483            }
2484            if (lrui <= mLruProcessActivityStart) {
2485                mLruProcessActivityStart--;
2486            }
2487            if (lrui <= mLruProcessServiceStart) {
2488                mLruProcessServiceStart--;
2489            }
2490            mLruProcesses.remove(lrui);
2491        }
2492    }
2493
2494    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2495            ProcessRecord client) {
2496        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2497                || app.treatLikeActivity;
2498        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2499        if (!activityChange && hasActivity) {
2500            // The process has activities, so we are only allowing activity-based adjustments
2501            // to move it.  It should be kept in the front of the list with other
2502            // processes that have activities, and we don't want those to change their
2503            // order except due to activity operations.
2504            return;
2505        }
2506
2507        mLruSeq++;
2508        final long now = SystemClock.uptimeMillis();
2509        app.lastActivityTime = now;
2510
2511        // First a quick reject: if the app is already at the position we will
2512        // put it, then there is nothing to do.
2513        if (hasActivity) {
2514            final int N = mLruProcesses.size();
2515            if (N > 0 && mLruProcesses.get(N-1) == app) {
2516                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2517                return;
2518            }
2519        } else {
2520            if (mLruProcessServiceStart > 0
2521                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2522                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2523                return;
2524            }
2525        }
2526
2527        int lrui = mLruProcesses.lastIndexOf(app);
2528
2529        if (app.persistent && lrui >= 0) {
2530            // We don't care about the position of persistent processes, as long as
2531            // they are in the list.
2532            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2533            return;
2534        }
2535
2536        /* In progress: compute new position first, so we can avoid doing work
2537           if the process is not actually going to move.  Not yet working.
2538        int addIndex;
2539        int nextIndex;
2540        boolean inActivity = false, inService = false;
2541        if (hasActivity) {
2542            // Process has activities, put it at the very tipsy-top.
2543            addIndex = mLruProcesses.size();
2544            nextIndex = mLruProcessServiceStart;
2545            inActivity = true;
2546        } else if (hasService) {
2547            // Process has services, put it at the top of the service list.
2548            addIndex = mLruProcessActivityStart;
2549            nextIndex = mLruProcessServiceStart;
2550            inActivity = true;
2551            inService = true;
2552        } else  {
2553            // Process not otherwise of interest, it goes to the top of the non-service area.
2554            addIndex = mLruProcessServiceStart;
2555            if (client != null) {
2556                int clientIndex = mLruProcesses.lastIndexOf(client);
2557                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2558                        + app);
2559                if (clientIndex >= 0 && addIndex > clientIndex) {
2560                    addIndex = clientIndex;
2561                }
2562            }
2563            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2564        }
2565
2566        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2567                + mLruProcessActivityStart + "): " + app);
2568        */
2569
2570        if (lrui >= 0) {
2571            if (lrui < mLruProcessActivityStart) {
2572                mLruProcessActivityStart--;
2573            }
2574            if (lrui < mLruProcessServiceStart) {
2575                mLruProcessServiceStart--;
2576            }
2577            /*
2578            if (addIndex > lrui) {
2579                addIndex--;
2580            }
2581            if (nextIndex > lrui) {
2582                nextIndex--;
2583            }
2584            */
2585            mLruProcesses.remove(lrui);
2586        }
2587
2588        /*
2589        mLruProcesses.add(addIndex, app);
2590        if (inActivity) {
2591            mLruProcessActivityStart++;
2592        }
2593        if (inService) {
2594            mLruProcessActivityStart++;
2595        }
2596        */
2597
2598        int nextIndex;
2599        if (hasActivity) {
2600            final int N = mLruProcesses.size();
2601            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2602                // Process doesn't have activities, but has clients with
2603                // activities...  move it up, but one below the top (the top
2604                // should always have a real activity).
2605                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2606                mLruProcesses.add(N-1, app);
2607                // To keep it from spamming the LRU list (by making a bunch of clients),
2608                // we will push down any other entries owned by the app.
2609                final int uid = app.info.uid;
2610                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2611                    ProcessRecord subProc = mLruProcesses.get(i);
2612                    if (subProc.info.uid == uid) {
2613                        // We want to push this one down the list.  If the process after
2614                        // it is for the same uid, however, don't do so, because we don't
2615                        // want them internally to be re-ordered.
2616                        if (mLruProcesses.get(i-1).info.uid != uid) {
2617                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2618                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2619                            ProcessRecord tmp = mLruProcesses.get(i);
2620                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2621                            mLruProcesses.set(i-1, tmp);
2622                            i--;
2623                        }
2624                    } else {
2625                        // A gap, we can stop here.
2626                        break;
2627                    }
2628                }
2629            } else {
2630                // Process has activities, put it at the very tipsy-top.
2631                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2632                mLruProcesses.add(app);
2633            }
2634            nextIndex = mLruProcessServiceStart;
2635        } else if (hasService) {
2636            // Process has services, put it at the top of the service list.
2637            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2638            mLruProcesses.add(mLruProcessActivityStart, app);
2639            nextIndex = mLruProcessServiceStart;
2640            mLruProcessActivityStart++;
2641        } else  {
2642            // Process not otherwise of interest, it goes to the top of the non-service area.
2643            int index = mLruProcessServiceStart;
2644            if (client != null) {
2645                // If there is a client, don't allow the process to be moved up higher
2646                // in the list than that client.
2647                int clientIndex = mLruProcesses.lastIndexOf(client);
2648                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2649                        + " when updating " + app);
2650                if (clientIndex <= lrui) {
2651                    // Don't allow the client index restriction to push it down farther in the
2652                    // list than it already is.
2653                    clientIndex = lrui;
2654                }
2655                if (clientIndex >= 0 && index > clientIndex) {
2656                    index = clientIndex;
2657                }
2658            }
2659            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2660            mLruProcesses.add(index, app);
2661            nextIndex = index-1;
2662            mLruProcessActivityStart++;
2663            mLruProcessServiceStart++;
2664        }
2665
2666        // If the app is currently using a content provider or service,
2667        // bump those processes as well.
2668        for (int j=app.connections.size()-1; j>=0; j--) {
2669            ConnectionRecord cr = app.connections.valueAt(j);
2670            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2671                    && cr.binding.service.app != null
2672                    && cr.binding.service.app.lruSeq != mLruSeq
2673                    && !cr.binding.service.app.persistent) {
2674                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2675                        "service connection", cr, app);
2676            }
2677        }
2678        for (int j=app.conProviders.size()-1; j>=0; j--) {
2679            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2680            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2681                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2682                        "provider reference", cpr, app);
2683            }
2684        }
2685    }
2686
2687    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2688        if (uid == Process.SYSTEM_UID) {
2689            // The system gets to run in any process.  If there are multiple
2690            // processes with the same uid, just pick the first (this
2691            // should never happen).
2692            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2693            if (procs == null) return null;
2694            final int N = procs.size();
2695            for (int i = 0; i < N; i++) {
2696                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2697            }
2698        }
2699        ProcessRecord proc = mProcessNames.get(processName, uid);
2700        if (false && proc != null && !keepIfLarge
2701                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2702                && proc.lastCachedPss >= 4000) {
2703            // Turn this condition on to cause killing to happen regularly, for testing.
2704            if (proc.baseProcessTracker != null) {
2705                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2706            }
2707            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2708        } else if (proc != null && !keepIfLarge
2709                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2710                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2711            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2712            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2713                if (proc.baseProcessTracker != null) {
2714                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2715                }
2716                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2717            }
2718        }
2719        return proc;
2720    }
2721
2722    void ensurePackageDexOpt(String packageName) {
2723        IPackageManager pm = AppGlobals.getPackageManager();
2724        try {
2725            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2726                mDidDexOpt = true;
2727            }
2728        } catch (RemoteException e) {
2729        }
2730    }
2731
2732    boolean isNextTransitionForward() {
2733        int transit = mWindowManager.getPendingAppTransition();
2734        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2735                || transit == AppTransition.TRANSIT_TASK_OPEN
2736                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2737    }
2738
2739    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2740            String processName, String abiOverride, int uid, Runnable crashHandler) {
2741        synchronized(this) {
2742            ApplicationInfo info = new ApplicationInfo();
2743            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2744            // For isolated processes, the former contains the parent's uid and the latter the
2745            // actual uid of the isolated process.
2746            // In the special case introduced by this method (which is, starting an isolated
2747            // process directly from the SystemServer without an actual parent app process) the
2748            // closest thing to a parent's uid is SYSTEM_UID.
2749            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2750            // the |isolated| logic in the ProcessRecord constructor.
2751            info.uid = Process.SYSTEM_UID;
2752            info.processName = processName;
2753            info.className = entryPoint;
2754            info.packageName = "android";
2755            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2756                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2757                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2758                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2759                    crashHandler);
2760            return proc != null ? proc.pid : 0;
2761        }
2762    }
2763
2764    final ProcessRecord startProcessLocked(String processName,
2765            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2766            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2767            boolean isolated, boolean keepIfLarge) {
2768        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2769                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2770                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2771                null /* crashHandler */);
2772    }
2773
2774    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2775            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2776            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2777            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2778        long startTime = SystemClock.elapsedRealtime();
2779        ProcessRecord app;
2780        if (!isolated) {
2781            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2782            checkTime(startTime, "startProcess: after getProcessRecord");
2783        } else {
2784            // If this is an isolated process, it can't re-use an existing process.
2785            app = null;
2786        }
2787        // We don't have to do anything more if:
2788        // (1) There is an existing application record; and
2789        // (2) The caller doesn't think it is dead, OR there is no thread
2790        //     object attached to it so we know it couldn't have crashed; and
2791        // (3) There is a pid assigned to it, so it is either starting or
2792        //     already running.
2793        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2794                + " app=" + app + " knownToBeDead=" + knownToBeDead
2795                + " thread=" + (app != null ? app.thread : null)
2796                + " pid=" + (app != null ? app.pid : -1));
2797        if (app != null && app.pid > 0) {
2798            if (!knownToBeDead || app.thread == null) {
2799                // We already have the app running, or are waiting for it to
2800                // come up (we have a pid but not yet its thread), so keep it.
2801                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2802                // If this is a new package in the process, add the package to the list
2803                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2804                checkTime(startTime, "startProcess: done, added package to proc");
2805                return app;
2806            }
2807
2808            // An application record is attached to a previous process,
2809            // clean it up now.
2810            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2811            checkTime(startTime, "startProcess: bad proc running, killing");
2812            Process.killProcessGroup(app.info.uid, app.pid);
2813            handleAppDiedLocked(app, true, true);
2814            checkTime(startTime, "startProcess: done killing old proc");
2815        }
2816
2817        String hostingNameStr = hostingName != null
2818                ? hostingName.flattenToShortString() : null;
2819
2820        if (!isolated) {
2821            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2822                // If we are in the background, then check to see if this process
2823                // is bad.  If so, we will just silently fail.
2824                if (mBadProcesses.get(info.processName, info.uid) != null) {
2825                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2826                            + "/" + info.processName);
2827                    return null;
2828                }
2829            } else {
2830                // When the user is explicitly starting a process, then clear its
2831                // crash count so that we won't make it bad until they see at
2832                // least one crash dialog again, and make the process good again
2833                // if it had been bad.
2834                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2835                        + "/" + info.processName);
2836                mProcessCrashTimes.remove(info.processName, info.uid);
2837                if (mBadProcesses.get(info.processName, info.uid) != null) {
2838                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2839                            UserHandle.getUserId(info.uid), info.uid,
2840                            info.processName);
2841                    mBadProcesses.remove(info.processName, info.uid);
2842                    if (app != null) {
2843                        app.bad = false;
2844                    }
2845                }
2846            }
2847        }
2848
2849        if (app == null) {
2850            checkTime(startTime, "startProcess: creating new process record");
2851            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2852            if (app == null) {
2853                Slog.w(TAG, "Failed making new process record for "
2854                        + processName + "/" + info.uid + " isolated=" + isolated);
2855                return null;
2856            }
2857            app.crashHandler = crashHandler;
2858            mProcessNames.put(processName, app.uid, app);
2859            if (isolated) {
2860                mIsolatedProcesses.put(app.uid, app);
2861            }
2862            checkTime(startTime, "startProcess: done creating new process record");
2863        } else {
2864            // If this is a new package in the process, add the package to the list
2865            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2866            checkTime(startTime, "startProcess: added package to existing proc");
2867        }
2868
2869        // If the system is not ready yet, then hold off on starting this
2870        // process until it is.
2871        if (!mProcessesReady
2872                && !isAllowedWhileBooting(info)
2873                && !allowWhileBooting) {
2874            if (!mProcessesOnHold.contains(app)) {
2875                mProcessesOnHold.add(app);
2876            }
2877            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2878            checkTime(startTime, "startProcess: returning with proc on hold");
2879            return app;
2880        }
2881
2882        checkTime(startTime, "startProcess: stepping in to startProcess");
2883        startProcessLocked(
2884                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2885        checkTime(startTime, "startProcess: done starting proc!");
2886        return (app.pid != 0) ? app : null;
2887    }
2888
2889    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2890        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2891    }
2892
2893    private final void startProcessLocked(ProcessRecord app,
2894            String hostingType, String hostingNameStr) {
2895        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2896                null /* entryPoint */, null /* entryPointArgs */);
2897    }
2898
2899    private final void startProcessLocked(ProcessRecord app, String hostingType,
2900            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2901        long startTime = SystemClock.elapsedRealtime();
2902        if (app.pid > 0 && app.pid != MY_PID) {
2903            checkTime(startTime, "startProcess: removing from pids map");
2904            synchronized (mPidsSelfLocked) {
2905                mPidsSelfLocked.remove(app.pid);
2906                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2907            }
2908            checkTime(startTime, "startProcess: done removing from pids map");
2909            app.setPid(0);
2910        }
2911
2912        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2913                "startProcessLocked removing on hold: " + app);
2914        mProcessesOnHold.remove(app);
2915
2916        checkTime(startTime, "startProcess: starting to update cpu stats");
2917        updateCpuStats();
2918        checkTime(startTime, "startProcess: done updating cpu stats");
2919
2920        try {
2921            int uid = app.uid;
2922
2923            int[] gids = null;
2924            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2925            if (!app.isolated) {
2926                int[] permGids = null;
2927                try {
2928                    checkTime(startTime, "startProcess: getting gids from package manager");
2929                    final PackageManager pm = mContext.getPackageManager();
2930                    permGids = pm.getPackageGids(app.info.packageName);
2931
2932                    if (Environment.isExternalStorageEmulated()) {
2933                        checkTime(startTime, "startProcess: checking external storage perm");
2934                        if (pm.checkPermission(
2935                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2936                                app.info.packageName) == PERMISSION_GRANTED) {
2937                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2938                        } else {
2939                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2940                        }
2941                    }
2942                } catch (PackageManager.NameNotFoundException e) {
2943                    Slog.w(TAG, "Unable to retrieve gids", e);
2944                }
2945
2946                /*
2947                 * Add shared application and profile GIDs so applications can share some
2948                 * resources like shared libraries and access user-wide resources
2949                 */
2950                if (permGids == null) {
2951                    gids = new int[2];
2952                } else {
2953                    gids = new int[permGids.length + 2];
2954                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2955                }
2956                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2957                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2958            }
2959            checkTime(startTime, "startProcess: building args");
2960            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2961                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2962                        && mTopComponent != null
2963                        && app.processName.equals(mTopComponent.getPackageName())) {
2964                    uid = 0;
2965                }
2966                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2967                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2968                    uid = 0;
2969                }
2970            }
2971            int debugFlags = 0;
2972            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2973                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2974                // Also turn on CheckJNI for debuggable apps. It's quite
2975                // awkward to turn on otherwise.
2976                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2977            }
2978            // Run the app in safe mode if its manifest requests so or the
2979            // system is booted in safe mode.
2980            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2981                mSafeMode == true) {
2982                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2983            }
2984            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2985                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2986            }
2987            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2988                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2989            }
2990            if ("1".equals(SystemProperties.get("debug.assert"))) {
2991                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2992            }
2993
2994            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2995            if (requiredAbi == null) {
2996                requiredAbi = Build.SUPPORTED_ABIS[0];
2997            }
2998
2999            String instructionSet = null;
3000            if (app.info.primaryCpuAbi != null) {
3001                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3002            }
3003
3004            app.gids = gids;
3005            app.requiredAbi = requiredAbi;
3006            app.instructionSet = instructionSet;
3007
3008            // Start the process.  It will either succeed and return a result containing
3009            // the PID of the new process, or else throw a RuntimeException.
3010            boolean isActivityProcess = (entryPoint == null);
3011            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3012            checkTime(startTime, "startProcess: asking zygote to start proc");
3013            Process.ProcessStartResult startResult = Process.start(entryPoint,
3014                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3015                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3016                    app.info.dataDir, entryPointArgs);
3017            checkTime(startTime, "startProcess: returned from zygote!");
3018
3019            if (app.isolated) {
3020                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3021            }
3022            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3023            checkTime(startTime, "startProcess: done updating battery stats");
3024
3025            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3026                    UserHandle.getUserId(uid), startResult.pid, uid,
3027                    app.processName, hostingType,
3028                    hostingNameStr != null ? hostingNameStr : "");
3029
3030            if (app.persistent) {
3031                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3032            }
3033
3034            checkTime(startTime, "startProcess: building log message");
3035            StringBuilder buf = mStringBuilder;
3036            buf.setLength(0);
3037            buf.append("Start proc ");
3038            buf.append(startResult.pid);
3039            buf.append(':');
3040            buf.append(app.processName);
3041            buf.append('/');
3042            UserHandle.formatUid(buf, uid);
3043            if (!isActivityProcess) {
3044                buf.append(" [");
3045                buf.append(entryPoint);
3046                buf.append("]");
3047            }
3048            buf.append(" for ");
3049            buf.append(hostingType);
3050            if (hostingNameStr != null) {
3051                buf.append(" ");
3052                buf.append(hostingNameStr);
3053            }
3054            Slog.i(TAG, buf.toString());
3055            app.setPid(startResult.pid);
3056            app.usingWrapper = startResult.usingWrapper;
3057            app.removed = false;
3058            app.killed = false;
3059            app.killedByAm = false;
3060            checkTime(startTime, "startProcess: starting to update pids map");
3061            synchronized (mPidsSelfLocked) {
3062                this.mPidsSelfLocked.put(startResult.pid, app);
3063                if (isActivityProcess) {
3064                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3065                    msg.obj = app;
3066                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3067                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3068                }
3069            }
3070            checkTime(startTime, "startProcess: done updating pids map");
3071        } catch (RuntimeException e) {
3072            // XXX do better error recovery.
3073            app.setPid(0);
3074            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3075            if (app.isolated) {
3076                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3077            }
3078            Slog.e(TAG, "Failure starting process " + app.processName, e);
3079        }
3080    }
3081
3082    void updateUsageStats(ActivityRecord component, boolean resumed) {
3083        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3084        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3085        if (resumed) {
3086            if (mUsageStatsService != null) {
3087                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3088                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3089            }
3090            synchronized (stats) {
3091                stats.noteActivityResumedLocked(component.app.uid);
3092            }
3093        } else {
3094            if (mUsageStatsService != null) {
3095                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3096                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3097            }
3098            synchronized (stats) {
3099                stats.noteActivityPausedLocked(component.app.uid);
3100            }
3101        }
3102    }
3103
3104    Intent getHomeIntent() {
3105        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3106        intent.setComponent(mTopComponent);
3107        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3108            intent.addCategory(Intent.CATEGORY_HOME);
3109        }
3110        return intent;
3111    }
3112
3113    boolean startHomeActivityLocked(int userId, String reason) {
3114        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3115                && mTopAction == null) {
3116            // We are running in factory test mode, but unable to find
3117            // the factory test app, so just sit around displaying the
3118            // error message and don't try to start anything.
3119            return false;
3120        }
3121        Intent intent = getHomeIntent();
3122        ActivityInfo aInfo =
3123            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3124        if (aInfo != null) {
3125            intent.setComponent(new ComponentName(
3126                    aInfo.applicationInfo.packageName, aInfo.name));
3127            // Don't do this if the home app is currently being
3128            // instrumented.
3129            aInfo = new ActivityInfo(aInfo);
3130            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3131            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3132                    aInfo.applicationInfo.uid, true);
3133            if (app == null || app.instrumentationClass == null) {
3134                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3135                mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3136            }
3137        }
3138
3139        return true;
3140    }
3141
3142    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3143        ActivityInfo ai = null;
3144        ComponentName comp = intent.getComponent();
3145        try {
3146            if (comp != null) {
3147                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3148            } else {
3149                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3150                        intent,
3151                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3152                            flags, userId);
3153
3154                if (info != null) {
3155                    ai = info.activityInfo;
3156                }
3157            }
3158        } catch (RemoteException e) {
3159            // ignore
3160        }
3161
3162        return ai;
3163    }
3164
3165    /**
3166     * Starts the "new version setup screen" if appropriate.
3167     */
3168    void startSetupActivityLocked() {
3169        // Only do this once per boot.
3170        if (mCheckedForSetup) {
3171            return;
3172        }
3173
3174        // We will show this screen if the current one is a different
3175        // version than the last one shown, and we are not running in
3176        // low-level factory test mode.
3177        final ContentResolver resolver = mContext.getContentResolver();
3178        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3179                Settings.Global.getInt(resolver,
3180                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3181            mCheckedForSetup = true;
3182
3183            // See if we should be showing the platform update setup UI.
3184            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3185            List<ResolveInfo> ris = mContext.getPackageManager()
3186                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3187
3188            // We don't allow third party apps to replace this.
3189            ResolveInfo ri = null;
3190            for (int i=0; ris != null && i<ris.size(); i++) {
3191                if ((ris.get(i).activityInfo.applicationInfo.flags
3192                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3193                    ri = ris.get(i);
3194                    break;
3195                }
3196            }
3197
3198            if (ri != null) {
3199                String vers = ri.activityInfo.metaData != null
3200                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3201                        : null;
3202                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3203                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3204                            Intent.METADATA_SETUP_VERSION);
3205                }
3206                String lastVers = Settings.Secure.getString(
3207                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3208                if (vers != null && !vers.equals(lastVers)) {
3209                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3210                    intent.setComponent(new ComponentName(
3211                            ri.activityInfo.packageName, ri.activityInfo.name));
3212                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3213                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3214                            null);
3215                }
3216            }
3217        }
3218    }
3219
3220    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3221        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3222    }
3223
3224    void enforceNotIsolatedCaller(String caller) {
3225        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3226            throw new SecurityException("Isolated process not allowed to call " + caller);
3227        }
3228    }
3229
3230    void enforceShellRestriction(String restriction, int userHandle) {
3231        if (Binder.getCallingUid() == Process.SHELL_UID) {
3232            if (userHandle < 0
3233                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3234                throw new SecurityException("Shell does not have permission to access user "
3235                        + userHandle);
3236            }
3237        }
3238    }
3239
3240    @Override
3241    public int getFrontActivityScreenCompatMode() {
3242        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3243        synchronized (this) {
3244            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3245        }
3246    }
3247
3248    @Override
3249    public void setFrontActivityScreenCompatMode(int mode) {
3250        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3251                "setFrontActivityScreenCompatMode");
3252        synchronized (this) {
3253            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3254        }
3255    }
3256
3257    @Override
3258    public int getPackageScreenCompatMode(String packageName) {
3259        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3260        synchronized (this) {
3261            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3262        }
3263    }
3264
3265    @Override
3266    public void setPackageScreenCompatMode(String packageName, int mode) {
3267        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3268                "setPackageScreenCompatMode");
3269        synchronized (this) {
3270            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3271        }
3272    }
3273
3274    @Override
3275    public boolean getPackageAskScreenCompat(String packageName) {
3276        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3277        synchronized (this) {
3278            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3279        }
3280    }
3281
3282    @Override
3283    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3284        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3285                "setPackageAskScreenCompat");
3286        synchronized (this) {
3287            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3288        }
3289    }
3290
3291    private void dispatchProcessesChanged() {
3292        int N;
3293        synchronized (this) {
3294            N = mPendingProcessChanges.size();
3295            if (mActiveProcessChanges.length < N) {
3296                mActiveProcessChanges = new ProcessChangeItem[N];
3297            }
3298            mPendingProcessChanges.toArray(mActiveProcessChanges);
3299            mAvailProcessChanges.addAll(mPendingProcessChanges);
3300            mPendingProcessChanges.clear();
3301            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3302        }
3303
3304        int i = mProcessObservers.beginBroadcast();
3305        while (i > 0) {
3306            i--;
3307            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3308            if (observer != null) {
3309                try {
3310                    for (int j=0; j<N; j++) {
3311                        ProcessChangeItem item = mActiveProcessChanges[j];
3312                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3313                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3314                                    + item.pid + " uid=" + item.uid + ": "
3315                                    + item.foregroundActivities);
3316                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3317                                    item.foregroundActivities);
3318                        }
3319                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3320                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3321                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3322                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3323                        }
3324                    }
3325                } catch (RemoteException e) {
3326                }
3327            }
3328        }
3329        mProcessObservers.finishBroadcast();
3330    }
3331
3332    private void dispatchProcessDied(int pid, int uid) {
3333        int i = mProcessObservers.beginBroadcast();
3334        while (i > 0) {
3335            i--;
3336            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3337            if (observer != null) {
3338                try {
3339                    observer.onProcessDied(pid, uid);
3340                } catch (RemoteException e) {
3341                }
3342            }
3343        }
3344        mProcessObservers.finishBroadcast();
3345    }
3346
3347    @Override
3348    public final int startActivity(IApplicationThread caller, String callingPackage,
3349            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3350            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3351        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3352            resultWho, requestCode, startFlags, profilerInfo, options,
3353            UserHandle.getCallingUserId());
3354    }
3355
3356    @Override
3357    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3358            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3359            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3360        enforceNotIsolatedCaller("startActivity");
3361        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3362                false, ALLOW_FULL_ONLY, "startActivity", null);
3363        // TODO: Switch to user app stacks here.
3364        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3365                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3366                profilerInfo, null, null, options, userId, null, null);
3367    }
3368
3369    @Override
3370    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3371            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3372            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3373
3374        // This is very dangerous -- it allows you to perform a start activity (including
3375        // permission grants) as any app that may launch one of your own activities.  So
3376        // we will only allow this to be done from activities that are part of the core framework,
3377        // and then only when they are running as the system.
3378        final ActivityRecord sourceRecord;
3379        final int targetUid;
3380        final String targetPackage;
3381        synchronized (this) {
3382            if (resultTo == null) {
3383                throw new SecurityException("Must be called from an activity");
3384            }
3385            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3386            if (sourceRecord == null) {
3387                throw new SecurityException("Called with bad activity token: " + resultTo);
3388            }
3389            if (!sourceRecord.info.packageName.equals("android")) {
3390                throw new SecurityException(
3391                        "Must be called from an activity that is declared in the android package");
3392            }
3393            if (sourceRecord.app == null) {
3394                throw new SecurityException("Called without a process attached to activity");
3395            }
3396            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3397                // This is still okay, as long as this activity is running under the
3398                // uid of the original calling activity.
3399                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3400                    throw new SecurityException(
3401                            "Calling activity in uid " + sourceRecord.app.uid
3402                                    + " must be system uid or original calling uid "
3403                                    + sourceRecord.launchedFromUid);
3404                }
3405            }
3406            targetUid = sourceRecord.launchedFromUid;
3407            targetPackage = sourceRecord.launchedFromPackage;
3408        }
3409
3410        if (userId == UserHandle.USER_NULL) {
3411            userId = UserHandle.getUserId(sourceRecord.app.uid);
3412        }
3413
3414        // TODO: Switch to user app stacks here.
3415        try {
3416            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3417                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3418                    null, null, options, userId, null, null);
3419            return ret;
3420        } catch (SecurityException e) {
3421            // XXX need to figure out how to propagate to original app.
3422            // A SecurityException here is generally actually a fault of the original
3423            // calling activity (such as a fairly granting permissions), so propagate it
3424            // back to them.
3425            /*
3426            StringBuilder msg = new StringBuilder();
3427            msg.append("While launching");
3428            msg.append(intent.toString());
3429            msg.append(": ");
3430            msg.append(e.getMessage());
3431            */
3432            throw e;
3433        }
3434    }
3435
3436    @Override
3437    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3438            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3439            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3440        enforceNotIsolatedCaller("startActivityAndWait");
3441        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3442                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3443        WaitResult res = new WaitResult();
3444        // TODO: Switch to user app stacks here.
3445        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3446                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3447                options, userId, null, null);
3448        return res;
3449    }
3450
3451    @Override
3452    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3453            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3454            int startFlags, Configuration config, Bundle options, int userId) {
3455        enforceNotIsolatedCaller("startActivityWithConfig");
3456        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3457                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3458        // TODO: Switch to user app stacks here.
3459        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3460                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3461                null, null, config, options, userId, null, null);
3462        return ret;
3463    }
3464
3465    @Override
3466    public int startActivityIntentSender(IApplicationThread caller,
3467            IntentSender intent, Intent fillInIntent, String resolvedType,
3468            IBinder resultTo, String resultWho, int requestCode,
3469            int flagsMask, int flagsValues, Bundle options) {
3470        enforceNotIsolatedCaller("startActivityIntentSender");
3471        // Refuse possible leaked file descriptors
3472        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3473            throw new IllegalArgumentException("File descriptors passed in Intent");
3474        }
3475
3476        IIntentSender sender = intent.getTarget();
3477        if (!(sender instanceof PendingIntentRecord)) {
3478            throw new IllegalArgumentException("Bad PendingIntent object");
3479        }
3480
3481        PendingIntentRecord pir = (PendingIntentRecord)sender;
3482
3483        synchronized (this) {
3484            // If this is coming from the currently resumed activity, it is
3485            // effectively saying that app switches are allowed at this point.
3486            final ActivityStack stack = getFocusedStack();
3487            if (stack.mResumedActivity != null &&
3488                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3489                mAppSwitchesAllowedTime = 0;
3490            }
3491        }
3492        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3493                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3494        return ret;
3495    }
3496
3497    @Override
3498    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3499            Intent intent, String resolvedType, IVoiceInteractionSession session,
3500            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3501            Bundle options, int userId) {
3502        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3503                != PackageManager.PERMISSION_GRANTED) {
3504            String msg = "Permission Denial: startVoiceActivity() from pid="
3505                    + Binder.getCallingPid()
3506                    + ", uid=" + Binder.getCallingUid()
3507                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3508            Slog.w(TAG, msg);
3509            throw new SecurityException(msg);
3510        }
3511        if (session == null || interactor == null) {
3512            throw new NullPointerException("null session or interactor");
3513        }
3514        userId = handleIncomingUser(callingPid, callingUid, userId,
3515                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3516        // TODO: Switch to user app stacks here.
3517        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3518                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3519                null, options, userId, null, null);
3520    }
3521
3522    @Override
3523    public boolean startNextMatchingActivity(IBinder callingActivity,
3524            Intent intent, Bundle options) {
3525        // Refuse possible leaked file descriptors
3526        if (intent != null && intent.hasFileDescriptors() == true) {
3527            throw new IllegalArgumentException("File descriptors passed in Intent");
3528        }
3529
3530        synchronized (this) {
3531            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3532            if (r == null) {
3533                ActivityOptions.abort(options);
3534                return false;
3535            }
3536            if (r.app == null || r.app.thread == null) {
3537                // The caller is not running...  d'oh!
3538                ActivityOptions.abort(options);
3539                return false;
3540            }
3541            intent = new Intent(intent);
3542            // The caller is not allowed to change the data.
3543            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3544            // And we are resetting to find the next component...
3545            intent.setComponent(null);
3546
3547            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3548
3549            ActivityInfo aInfo = null;
3550            try {
3551                List<ResolveInfo> resolves =
3552                    AppGlobals.getPackageManager().queryIntentActivities(
3553                            intent, r.resolvedType,
3554                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3555                            UserHandle.getCallingUserId());
3556
3557                // Look for the original activity in the list...
3558                final int N = resolves != null ? resolves.size() : 0;
3559                for (int i=0; i<N; i++) {
3560                    ResolveInfo rInfo = resolves.get(i);
3561                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3562                            && rInfo.activityInfo.name.equals(r.info.name)) {
3563                        // We found the current one...  the next matching is
3564                        // after it.
3565                        i++;
3566                        if (i<N) {
3567                            aInfo = resolves.get(i).activityInfo;
3568                        }
3569                        if (debug) {
3570                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3571                                    + "/" + r.info.name);
3572                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3573                                    + "/" + aInfo.name);
3574                        }
3575                        break;
3576                    }
3577                }
3578            } catch (RemoteException e) {
3579            }
3580
3581            if (aInfo == null) {
3582                // Nobody who is next!
3583                ActivityOptions.abort(options);
3584                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3585                return false;
3586            }
3587
3588            intent.setComponent(new ComponentName(
3589                    aInfo.applicationInfo.packageName, aInfo.name));
3590            intent.setFlags(intent.getFlags()&~(
3591                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3592                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3593                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3594                    Intent.FLAG_ACTIVITY_NEW_TASK));
3595
3596            // Okay now we need to start the new activity, replacing the
3597            // currently running activity.  This is a little tricky because
3598            // we want to start the new one as if the current one is finished,
3599            // but not finish the current one first so that there is no flicker.
3600            // And thus...
3601            final boolean wasFinishing = r.finishing;
3602            r.finishing = true;
3603
3604            // Propagate reply information over to the new activity.
3605            final ActivityRecord resultTo = r.resultTo;
3606            final String resultWho = r.resultWho;
3607            final int requestCode = r.requestCode;
3608            r.resultTo = null;
3609            if (resultTo != null) {
3610                resultTo.removeResultsLocked(r, resultWho, requestCode);
3611            }
3612
3613            final long origId = Binder.clearCallingIdentity();
3614            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3615                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3616                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3617                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3618            Binder.restoreCallingIdentity(origId);
3619
3620            r.finishing = wasFinishing;
3621            if (res != ActivityManager.START_SUCCESS) {
3622                return false;
3623            }
3624            return true;
3625        }
3626    }
3627
3628    @Override
3629    public final int startActivityFromRecents(int taskId, Bundle options) {
3630        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3631            String msg = "Permission Denial: startActivityFromRecents called without " +
3632                    START_TASKS_FROM_RECENTS;
3633            Slog.w(TAG, msg);
3634            throw new SecurityException(msg);
3635        }
3636        return startActivityFromRecentsInner(taskId, options);
3637    }
3638
3639    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3640        final TaskRecord task;
3641        final int callingUid;
3642        final String callingPackage;
3643        final Intent intent;
3644        final int userId;
3645        synchronized (this) {
3646            task = recentTaskForIdLocked(taskId);
3647            if (task == null) {
3648                throw new IllegalArgumentException("Task " + taskId + " not found.");
3649            }
3650            if (task.getRootActivity() != null) {
3651                moveTaskToFrontLocked(task.taskId, 0, null);
3652                return ActivityManager.START_TASK_TO_FRONT;
3653            }
3654            callingUid = task.mCallingUid;
3655            callingPackage = task.mCallingPackage;
3656            intent = task.intent;
3657            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3658            userId = task.userId;
3659        }
3660        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3661                options, userId, null, task);
3662    }
3663
3664    final int startActivityInPackage(int uid, String callingPackage,
3665            Intent intent, String resolvedType, IBinder resultTo,
3666            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3667            IActivityContainer container, TaskRecord inTask) {
3668
3669        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3670                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3671
3672        // TODO: Switch to user app stacks here.
3673        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3674                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3675                null, null, null, options, userId, container, inTask);
3676        return ret;
3677    }
3678
3679    @Override
3680    public final int startActivities(IApplicationThread caller, String callingPackage,
3681            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3682            int userId) {
3683        enforceNotIsolatedCaller("startActivities");
3684        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3685                false, ALLOW_FULL_ONLY, "startActivity", null);
3686        // TODO: Switch to user app stacks here.
3687        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3688                resolvedTypes, resultTo, options, userId);
3689        return ret;
3690    }
3691
3692    final int startActivitiesInPackage(int uid, String callingPackage,
3693            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3694            Bundle options, int userId) {
3695
3696        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3697                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3698        // TODO: Switch to user app stacks here.
3699        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3700                resultTo, options, userId);
3701        return ret;
3702    }
3703
3704    //explicitly remove thd old information in mRecentTasks when removing existing user.
3705    private void removeRecentTasksForUserLocked(int userId) {
3706        if(userId <= 0) {
3707            Slog.i(TAG, "Can't remove recent task on user " + userId);
3708            return;
3709        }
3710
3711        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3712            TaskRecord tr = mRecentTasks.get(i);
3713            if (tr.userId == userId) {
3714                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3715                        + " when finishing user" + userId);
3716                mRecentTasks.remove(i);
3717                tr.removedFromRecents();
3718            }
3719        }
3720
3721        // Remove tasks from persistent storage.
3722        notifyTaskPersisterLocked(null, true);
3723    }
3724
3725    // Sort by taskId
3726    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3727        @Override
3728        public int compare(TaskRecord lhs, TaskRecord rhs) {
3729            return rhs.taskId - lhs.taskId;
3730        }
3731    };
3732
3733    // Extract the affiliates of the chain containing mRecentTasks[start].
3734    private int processNextAffiliateChainLocked(int start) {
3735        final TaskRecord startTask = mRecentTasks.get(start);
3736        final int affiliateId = startTask.mAffiliatedTaskId;
3737
3738        // Quick identification of isolated tasks. I.e. those not launched behind.
3739        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3740                startTask.mNextAffiliate == null) {
3741            // There is still a slim chance that there are other tasks that point to this task
3742            // and that the chain is so messed up that this task no longer points to them but
3743            // the gain of this optimization outweighs the risk.
3744            startTask.inRecents = true;
3745            return start + 1;
3746        }
3747
3748        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3749        mTmpRecents.clear();
3750        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3751            final TaskRecord task = mRecentTasks.get(i);
3752            if (task.mAffiliatedTaskId == affiliateId) {
3753                mRecentTasks.remove(i);
3754                mTmpRecents.add(task);
3755            }
3756        }
3757
3758        // Sort them all by taskId. That is the order they were create in and that order will
3759        // always be correct.
3760        Collections.sort(mTmpRecents, mTaskRecordComparator);
3761
3762        // Go through and fix up the linked list.
3763        // The first one is the end of the chain and has no next.
3764        final TaskRecord first = mTmpRecents.get(0);
3765        first.inRecents = true;
3766        if (first.mNextAffiliate != null) {
3767            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3768            first.setNextAffiliate(null);
3769            notifyTaskPersisterLocked(first, false);
3770        }
3771        // Everything in the middle is doubly linked from next to prev.
3772        final int tmpSize = mTmpRecents.size();
3773        for (int i = 0; i < tmpSize - 1; ++i) {
3774            final TaskRecord next = mTmpRecents.get(i);
3775            final TaskRecord prev = mTmpRecents.get(i + 1);
3776            if (next.mPrevAffiliate != prev) {
3777                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3778                        " setting prev=" + prev);
3779                next.setPrevAffiliate(prev);
3780                notifyTaskPersisterLocked(next, false);
3781            }
3782            if (prev.mNextAffiliate != next) {
3783                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3784                        " setting next=" + next);
3785                prev.setNextAffiliate(next);
3786                notifyTaskPersisterLocked(prev, false);
3787            }
3788            prev.inRecents = true;
3789        }
3790        // The last one is the beginning of the list and has no prev.
3791        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3792        if (last.mPrevAffiliate != null) {
3793            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3794            last.setPrevAffiliate(null);
3795            notifyTaskPersisterLocked(last, false);
3796        }
3797
3798        // Insert the group back into mRecentTasks at start.
3799        mRecentTasks.addAll(start, mTmpRecents);
3800
3801        // Let the caller know where we left off.
3802        return start + tmpSize;
3803    }
3804
3805    /**
3806     * Update the recent tasks lists: make sure tasks should still be here (their
3807     * applications / activities still exist), update their availability, fixup ordering
3808     * of affiliations.
3809     */
3810    void cleanupRecentTasksLocked(int userId) {
3811        if (mRecentTasks == null) {
3812            // Happens when called from the packagemanager broadcast before boot.
3813            return;
3814        }
3815
3816        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3817        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3818        final IPackageManager pm = AppGlobals.getPackageManager();
3819        final ActivityInfo dummyAct = new ActivityInfo();
3820        final ApplicationInfo dummyApp = new ApplicationInfo();
3821
3822        int N = mRecentTasks.size();
3823
3824        int[] users = userId == UserHandle.USER_ALL
3825                ? getUsersLocked() : new int[] { userId };
3826        for (int user : users) {
3827            for (int i = 0; i < N; i++) {
3828                TaskRecord task = mRecentTasks.get(i);
3829                if (task.userId != user) {
3830                    // Only look at tasks for the user ID of interest.
3831                    continue;
3832                }
3833                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3834                    // This situation is broken, and we should just get rid of it now.
3835                    mRecentTasks.remove(i);
3836                    task.removedFromRecents();
3837                    i--;
3838                    N--;
3839                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3840                    continue;
3841                }
3842                // Check whether this activity is currently available.
3843                if (task.realActivity != null) {
3844                    ActivityInfo ai = availActCache.get(task.realActivity);
3845                    if (ai == null) {
3846                        try {
3847                            ai = pm.getActivityInfo(task.realActivity,
3848                                    PackageManager.GET_UNINSTALLED_PACKAGES
3849                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3850                        } catch (RemoteException e) {
3851                            // Will never happen.
3852                            continue;
3853                        }
3854                        if (ai == null) {
3855                            ai = dummyAct;
3856                        }
3857                        availActCache.put(task.realActivity, ai);
3858                    }
3859                    if (ai == dummyAct) {
3860                        // This could be either because the activity no longer exists, or the
3861                        // app is temporarily gone.  For the former we want to remove the recents
3862                        // entry; for the latter we want to mark it as unavailable.
3863                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3864                        if (app == null) {
3865                            try {
3866                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3867                                        PackageManager.GET_UNINSTALLED_PACKAGES
3868                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3869                            } catch (RemoteException e) {
3870                                // Will never happen.
3871                                continue;
3872                            }
3873                            if (app == null) {
3874                                app = dummyApp;
3875                            }
3876                            availAppCache.put(task.realActivity.getPackageName(), app);
3877                        }
3878                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3879                            // Doesn't exist any more!  Good-bye.
3880                            mRecentTasks.remove(i);
3881                            task.removedFromRecents();
3882                            i--;
3883                            N--;
3884                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3885                            continue;
3886                        } else {
3887                            // Otherwise just not available for now.
3888                            if (task.isAvailable) {
3889                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3890                                        + task);
3891                            }
3892                            task.isAvailable = false;
3893                        }
3894                    } else {
3895                        if (!ai.enabled || !ai.applicationInfo.enabled
3896                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3897                            if (task.isAvailable) {
3898                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3899                                        + task + " (enabled=" + ai.enabled + "/"
3900                                        + ai.applicationInfo.enabled +  " flags="
3901                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3902                            }
3903                            task.isAvailable = false;
3904                        } else {
3905                            if (!task.isAvailable) {
3906                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3907                                        + task);
3908                            }
3909                            task.isAvailable = true;
3910                        }
3911                    }
3912                }
3913            }
3914        }
3915
3916        // Verify the affiliate chain for each task.
3917        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3918        }
3919
3920        mTmpRecents.clear();
3921        // mRecentTasks is now in sorted, affiliated order.
3922    }
3923
3924    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3925        int N = mRecentTasks.size();
3926        TaskRecord top = task;
3927        int topIndex = taskIndex;
3928        while (top.mNextAffiliate != null && topIndex > 0) {
3929            top = top.mNextAffiliate;
3930            topIndex--;
3931        }
3932        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3933                + topIndex + " from intial " + taskIndex);
3934        // Find the end of the chain, doing a sanity check along the way.
3935        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3936        int endIndex = topIndex;
3937        TaskRecord prev = top;
3938        while (endIndex < N) {
3939            TaskRecord cur = mRecentTasks.get(endIndex);
3940            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3941                    + endIndex + " " + cur);
3942            if (cur == top) {
3943                // Verify start of the chain.
3944                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3945                    Slog.wtf(TAG, "Bad chain @" + endIndex
3946                            + ": first task has next affiliate: " + prev);
3947                    sane = false;
3948                    break;
3949                }
3950            } else {
3951                // Verify middle of the chain's next points back to the one before.
3952                if (cur.mNextAffiliate != prev
3953                        || cur.mNextAffiliateTaskId != prev.taskId) {
3954                    Slog.wtf(TAG, "Bad chain @" + endIndex
3955                            + ": middle task " + cur + " @" + endIndex
3956                            + " has bad next affiliate "
3957                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3958                            + ", expected " + prev);
3959                    sane = false;
3960                    break;
3961                }
3962            }
3963            if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
3964                // Chain ends here.
3965                if (cur.mPrevAffiliate != null) {
3966                    Slog.wtf(TAG, "Bad chain @" + endIndex
3967                            + ": last task " + cur + " has previous affiliate "
3968                            + cur.mPrevAffiliate);
3969                    sane = false;
3970                }
3971                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3972                break;
3973            } else {
3974                // Verify middle of the chain's prev points to a valid item.
3975                if (cur.mPrevAffiliate == null) {
3976                    Slog.wtf(TAG, "Bad chain @" + endIndex
3977                            + ": task " + cur + " has previous affiliate "
3978                            + cur.mPrevAffiliate + " but should be id "
3979                            + cur.mPrevAffiliate);
3980                    sane = false;
3981                    break;
3982                }
3983            }
3984            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3985                Slog.wtf(TAG, "Bad chain @" + endIndex
3986                        + ": task " + cur + " has affiliated id "
3987                        + cur.mAffiliatedTaskId + " but should be "
3988                        + task.mAffiliatedTaskId);
3989                sane = false;
3990                break;
3991            }
3992            prev = cur;
3993            endIndex++;
3994            if (endIndex >= N) {
3995                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3996                        + ": last task " + prev);
3997                sane = false;
3998                break;
3999            }
4000        }
4001        if (sane) {
4002            if (endIndex < taskIndex) {
4003                Slog.wtf(TAG, "Bad chain @" + endIndex
4004                        + ": did not extend to task " + task + " @" + taskIndex);
4005                sane = false;
4006            }
4007        }
4008        if (sane) {
4009            // All looks good, we can just move all of the affiliated tasks
4010            // to the top.
4011            for (int i=topIndex; i<=endIndex; i++) {
4012                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4013                        + " from " + i + " to " + (i-topIndex));
4014                TaskRecord cur = mRecentTasks.remove(i);
4015                mRecentTasks.add(i-topIndex, cur);
4016            }
4017            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4018                    + " to " + endIndex);
4019            return true;
4020        }
4021
4022        // Whoops, couldn't do it.
4023        return false;
4024    }
4025
4026    final void addRecentTaskLocked(TaskRecord task) {
4027        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4028                || task.mNextAffiliateTaskId != INVALID_TASK_ID
4029                || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
4030
4031        int N = mRecentTasks.size();
4032        // Quick case: check if the top-most recent task is the same.
4033        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4034            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4035            return;
4036        }
4037        // Another quick case: check if this is part of a set of affiliated
4038        // tasks that are at the top.
4039        if (isAffiliated && N > 0 && task.inRecents
4040                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4041            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4042                    + " at top when adding " + task);
4043            return;
4044        }
4045        // Another quick case: never add voice sessions.
4046        if (task.voiceSession != null) {
4047            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4048            return;
4049        }
4050
4051        boolean needAffiliationFix = false;
4052
4053        // Slightly less quick case: the task is already in recents, so all we need
4054        // to do is move it.
4055        if (task.inRecents) {
4056            int taskIndex = mRecentTasks.indexOf(task);
4057            if (taskIndex >= 0) {
4058                if (!isAffiliated) {
4059                    // Simple case: this is not an affiliated task, so we just move it to the front.
4060                    mRecentTasks.remove(taskIndex);
4061                    mRecentTasks.add(0, task);
4062                    notifyTaskPersisterLocked(task, false);
4063                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4064                            + " from " + taskIndex);
4065                    return;
4066                } else {
4067                    // More complicated: need to keep all affiliated tasks together.
4068                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4069                        // All went well.
4070                        return;
4071                    }
4072
4073                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4074                    // everything and then go through our general path of adding a new task.
4075                    needAffiliationFix = true;
4076                }
4077            } else {
4078                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4079                needAffiliationFix = true;
4080            }
4081        }
4082
4083        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4084        trimRecentsForTaskLocked(task, true);
4085
4086        N = mRecentTasks.size();
4087        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4088            final TaskRecord tr = mRecentTasks.remove(N - 1);
4089            tr.removedFromRecents();
4090            N--;
4091        }
4092        task.inRecents = true;
4093        if (!isAffiliated || needAffiliationFix) {
4094            // If this is a simple non-affiliated task, or we had some failure trying to
4095            // handle it as part of an affilated task, then just place it at the top.
4096            mRecentTasks.add(0, task);
4097        } else if (isAffiliated) {
4098            // If this is a new affiliated task, then move all of the affiliated tasks
4099            // to the front and insert this new one.
4100            TaskRecord other = task.mNextAffiliate;
4101            if (other == null) {
4102                other = task.mPrevAffiliate;
4103            }
4104            if (other != null) {
4105                int otherIndex = mRecentTasks.indexOf(other);
4106                if (otherIndex >= 0) {
4107                    // Insert new task at appropriate location.
4108                    int taskIndex;
4109                    if (other == task.mNextAffiliate) {
4110                        // We found the index of our next affiliation, which is who is
4111                        // before us in the list, so add after that point.
4112                        taskIndex = otherIndex+1;
4113                    } else {
4114                        // We found the index of our previous affiliation, which is who is
4115                        // after us in the list, so add at their position.
4116                        taskIndex = otherIndex;
4117                    }
4118                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4119                            + taskIndex + ": " + task);
4120                    mRecentTasks.add(taskIndex, task);
4121
4122                    // Now move everything to the front.
4123                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4124                        // All went well.
4125                        return;
4126                    }
4127
4128                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4129                    // everything and then go through our general path of adding a new task.
4130                    needAffiliationFix = true;
4131                } else {
4132                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4133                            + other);
4134                    needAffiliationFix = true;
4135                }
4136            } else {
4137                if (DEBUG_RECENTS) Slog.d(TAG,
4138                        "addRecent: adding affiliated task without next/prev:" + task);
4139                needAffiliationFix = true;
4140            }
4141        }
4142        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4143
4144        if (needAffiliationFix) {
4145            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4146            cleanupRecentTasksLocked(task.userId);
4147        }
4148    }
4149
4150    /**
4151     * If needed, remove oldest existing entries in recents that are for the same kind
4152     * of task as the given one.
4153     */
4154    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4155        int N = mRecentTasks.size();
4156        final Intent intent = task.intent;
4157        final boolean document = intent != null && intent.isDocument();
4158
4159        int maxRecents = task.maxRecents - 1;
4160        for (int i=0; i<N; i++) {
4161            final TaskRecord tr = mRecentTasks.get(i);
4162            if (task != tr) {
4163                if (task.userId != tr.userId) {
4164                    continue;
4165                }
4166                if (i > MAX_RECENT_BITMAPS) {
4167                    tr.freeLastThumbnail();
4168                }
4169                final Intent trIntent = tr.intent;
4170                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4171                    (intent == null || !intent.filterEquals(trIntent))) {
4172                    continue;
4173                }
4174                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4175                if (document && trIsDocument) {
4176                    // These are the same document activity (not necessarily the same doc).
4177                    if (maxRecents > 0) {
4178                        --maxRecents;
4179                        continue;
4180                    }
4181                    // Hit the maximum number of documents for this task. Fall through
4182                    // and remove this document from recents.
4183                } else if (document || trIsDocument) {
4184                    // Only one of these is a document. Not the droid we're looking for.
4185                    continue;
4186                }
4187            }
4188
4189            if (!doTrim) {
4190                // If the caller is not actually asking for a trim, just tell them we reached
4191                // a point where the trim would happen.
4192                return i;
4193            }
4194
4195            // Either task and tr are the same or, their affinities match or their intents match
4196            // and neither of them is a document, or they are documents using the same activity
4197            // and their maxRecents has been reached.
4198            tr.disposeThumbnail();
4199            mRecentTasks.remove(i);
4200            if (task != tr) {
4201                tr.removedFromRecents();
4202            }
4203            i--;
4204            N--;
4205            if (task.intent == null) {
4206                // If the new recent task we are adding is not fully
4207                // specified, then replace it with the existing recent task.
4208                task = tr;
4209            }
4210            notifyTaskPersisterLocked(tr, false);
4211        }
4212
4213        return -1;
4214    }
4215
4216    @Override
4217    public void reportActivityFullyDrawn(IBinder token) {
4218        synchronized (this) {
4219            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4220            if (r == null) {
4221                return;
4222            }
4223            r.reportFullyDrawnLocked();
4224        }
4225    }
4226
4227    @Override
4228    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4229        synchronized (this) {
4230            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4231            if (r == null) {
4232                return;
4233            }
4234            final long origId = Binder.clearCallingIdentity();
4235            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4236            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4237                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4238            if (config != null) {
4239                r.frozenBeforeDestroy = true;
4240                if (!updateConfigurationLocked(config, r, false, false)) {
4241                    mStackSupervisor.resumeTopActivitiesLocked();
4242                }
4243            }
4244            Binder.restoreCallingIdentity(origId);
4245        }
4246    }
4247
4248    @Override
4249    public int getRequestedOrientation(IBinder token) {
4250        synchronized (this) {
4251            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4252            if (r == null) {
4253                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4254            }
4255            return mWindowManager.getAppOrientation(r.appToken);
4256        }
4257    }
4258
4259    /**
4260     * This is the internal entry point for handling Activity.finish().
4261     *
4262     * @param token The Binder token referencing the Activity we want to finish.
4263     * @param resultCode Result code, if any, from this Activity.
4264     * @param resultData Result data (Intent), if any, from this Activity.
4265     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4266     *            the root Activity in the task.
4267     *
4268     * @return Returns true if the activity successfully finished, or false if it is still running.
4269     */
4270    @Override
4271    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4272            boolean finishTask) {
4273        // Refuse possible leaked file descriptors
4274        if (resultData != null && resultData.hasFileDescriptors() == true) {
4275            throw new IllegalArgumentException("File descriptors passed in Intent");
4276        }
4277
4278        synchronized(this) {
4279            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4280            if (r == null) {
4281                return true;
4282            }
4283            // Keep track of the root activity of the task before we finish it
4284            TaskRecord tr = r.task;
4285            ActivityRecord rootR = tr.getRootActivity();
4286            if (rootR == null) {
4287                Slog.w(TAG, "Finishing task with all activities already finished");
4288            }
4289            // Do not allow task to finish in Lock Task mode.
4290            if (tr == mStackSupervisor.mLockTaskModeTask) {
4291                if (rootR == r) {
4292                    Slog.i(TAG, "Not finishing task in lock task mode");
4293                    mStackSupervisor.showLockTaskToast();
4294                    return false;
4295                }
4296            }
4297            if (mController != null) {
4298                // Find the first activity that is not finishing.
4299                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4300                if (next != null) {
4301                    // ask watcher if this is allowed
4302                    boolean resumeOK = true;
4303                    try {
4304                        resumeOK = mController.activityResuming(next.packageName);
4305                    } catch (RemoteException e) {
4306                        mController = null;
4307                        Watchdog.getInstance().setActivityController(null);
4308                    }
4309
4310                    if (!resumeOK) {
4311                        Slog.i(TAG, "Not finishing activity because controller resumed");
4312                        return false;
4313                    }
4314                }
4315            }
4316            final long origId = Binder.clearCallingIdentity();
4317            try {
4318                boolean res;
4319                if (finishTask && r == rootR) {
4320                    // If requested, remove the task that is associated to this activity only if it
4321                    // was the root activity in the task. The result code and data is ignored
4322                    // because we don't support returning them across task boundaries.
4323                    res = removeTaskByIdLocked(tr.taskId, false);
4324                    if (!res) {
4325                        Slog.i(TAG, "Removing task failed to finish activity");
4326                    }
4327                } else {
4328                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4329                            resultData, "app-request", true);
4330                    if (!res) {
4331                        Slog.i(TAG, "Failed to finish by app-request");
4332                    }
4333                }
4334                return res;
4335            } finally {
4336                Binder.restoreCallingIdentity(origId);
4337            }
4338        }
4339    }
4340
4341    @Override
4342    public final void finishHeavyWeightApp() {
4343        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4344                != PackageManager.PERMISSION_GRANTED) {
4345            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4346                    + Binder.getCallingPid()
4347                    + ", uid=" + Binder.getCallingUid()
4348                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4349            Slog.w(TAG, msg);
4350            throw new SecurityException(msg);
4351        }
4352
4353        synchronized(this) {
4354            if (mHeavyWeightProcess == null) {
4355                return;
4356            }
4357
4358            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4359                    mHeavyWeightProcess.activities);
4360            for (int i=0; i<activities.size(); i++) {
4361                ActivityRecord r = activities.get(i);
4362                if (!r.finishing) {
4363                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4364                            null, "finish-heavy", true);
4365                }
4366            }
4367
4368            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4369                    mHeavyWeightProcess.userId, 0));
4370            mHeavyWeightProcess = null;
4371        }
4372    }
4373
4374    @Override
4375    public void crashApplication(int uid, int initialPid, String packageName,
4376            String message) {
4377        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4378                != PackageManager.PERMISSION_GRANTED) {
4379            String msg = "Permission Denial: crashApplication() from pid="
4380                    + Binder.getCallingPid()
4381                    + ", uid=" + Binder.getCallingUid()
4382                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4383            Slog.w(TAG, msg);
4384            throw new SecurityException(msg);
4385        }
4386
4387        synchronized(this) {
4388            ProcessRecord proc = null;
4389
4390            // Figure out which process to kill.  We don't trust that initialPid
4391            // still has any relation to current pids, so must scan through the
4392            // list.
4393            synchronized (mPidsSelfLocked) {
4394                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4395                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4396                    if (p.uid != uid) {
4397                        continue;
4398                    }
4399                    if (p.pid == initialPid) {
4400                        proc = p;
4401                        break;
4402                    }
4403                    if (p.pkgList.containsKey(packageName)) {
4404                        proc = p;
4405                    }
4406                }
4407            }
4408
4409            if (proc == null) {
4410                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4411                        + " initialPid=" + initialPid
4412                        + " packageName=" + packageName);
4413                return;
4414            }
4415
4416            if (proc.thread != null) {
4417                if (proc.pid == Process.myPid()) {
4418                    Log.w(TAG, "crashApplication: trying to crash self!");
4419                    return;
4420                }
4421                long ident = Binder.clearCallingIdentity();
4422                try {
4423                    proc.thread.scheduleCrash(message);
4424                } catch (RemoteException e) {
4425                }
4426                Binder.restoreCallingIdentity(ident);
4427            }
4428        }
4429    }
4430
4431    @Override
4432    public final void finishSubActivity(IBinder token, String resultWho,
4433            int requestCode) {
4434        synchronized(this) {
4435            final long origId = Binder.clearCallingIdentity();
4436            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4437            if (r != null) {
4438                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4439            }
4440            Binder.restoreCallingIdentity(origId);
4441        }
4442    }
4443
4444    @Override
4445    public boolean finishActivityAffinity(IBinder token) {
4446        synchronized(this) {
4447            final long origId = Binder.clearCallingIdentity();
4448            try {
4449                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4450
4451                ActivityRecord rootR = r.task.getRootActivity();
4452                // Do not allow task to finish in Lock Task mode.
4453                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4454                    if (rootR == r) {
4455                        mStackSupervisor.showLockTaskToast();
4456                        return false;
4457                    }
4458                }
4459                boolean res = false;
4460                if (r != null) {
4461                    res = r.task.stack.finishActivityAffinityLocked(r);
4462                }
4463                return res;
4464            } finally {
4465                Binder.restoreCallingIdentity(origId);
4466            }
4467        }
4468    }
4469
4470    @Override
4471    public void finishVoiceTask(IVoiceInteractionSession session) {
4472        synchronized(this) {
4473            final long origId = Binder.clearCallingIdentity();
4474            try {
4475                mStackSupervisor.finishVoiceTask(session);
4476            } finally {
4477                Binder.restoreCallingIdentity(origId);
4478            }
4479        }
4480
4481    }
4482
4483    @Override
4484    public boolean releaseActivityInstance(IBinder token) {
4485        synchronized(this) {
4486            final long origId = Binder.clearCallingIdentity();
4487            try {
4488                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4489                if (r.task == null || r.task.stack == null) {
4490                    return false;
4491                }
4492                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4493            } finally {
4494                Binder.restoreCallingIdentity(origId);
4495            }
4496        }
4497    }
4498
4499    @Override
4500    public void releaseSomeActivities(IApplicationThread appInt) {
4501        synchronized(this) {
4502            final long origId = Binder.clearCallingIdentity();
4503            try {
4504                ProcessRecord app = getRecordForAppLocked(appInt);
4505                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4506            } finally {
4507                Binder.restoreCallingIdentity(origId);
4508            }
4509        }
4510    }
4511
4512    @Override
4513    public boolean willActivityBeVisible(IBinder token) {
4514        synchronized(this) {
4515            ActivityStack stack = ActivityRecord.getStackLocked(token);
4516            if (stack != null) {
4517                return stack.willActivityBeVisibleLocked(token);
4518            }
4519            return false;
4520        }
4521    }
4522
4523    @Override
4524    public void overridePendingTransition(IBinder token, String packageName,
4525            int enterAnim, int exitAnim) {
4526        synchronized(this) {
4527            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4528            if (self == null) {
4529                return;
4530            }
4531
4532            final long origId = Binder.clearCallingIdentity();
4533
4534            if (self.state == ActivityState.RESUMED
4535                    || self.state == ActivityState.PAUSING) {
4536                mWindowManager.overridePendingAppTransition(packageName,
4537                        enterAnim, exitAnim, null);
4538            }
4539
4540            Binder.restoreCallingIdentity(origId);
4541        }
4542    }
4543
4544    /**
4545     * Main function for removing an existing process from the activity manager
4546     * as a result of that process going away.  Clears out all connections
4547     * to the process.
4548     */
4549    private final void handleAppDiedLocked(ProcessRecord app,
4550            boolean restarting, boolean allowRestart) {
4551        int pid = app.pid;
4552        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4553        if (!kept && !restarting) {
4554            removeLruProcessLocked(app);
4555            if (pid > 0) {
4556                ProcessList.remove(pid);
4557            }
4558        }
4559
4560        if (mProfileProc == app) {
4561            clearProfilerLocked();
4562        }
4563
4564        // Remove this application's activities from active lists.
4565        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4566
4567        app.activities.clear();
4568
4569        if (app.instrumentationClass != null) {
4570            Slog.w(TAG, "Crash of app " + app.processName
4571                  + " running instrumentation " + app.instrumentationClass);
4572            Bundle info = new Bundle();
4573            info.putString("shortMsg", "Process crashed.");
4574            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4575        }
4576
4577        if (!restarting) {
4578            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4579                // If there was nothing to resume, and we are not already
4580                // restarting this process, but there is a visible activity that
4581                // is hosted by the process...  then make sure all visible
4582                // activities are running, taking care of restarting this
4583                // process.
4584                if (hasVisibleActivities) {
4585                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4586                }
4587            }
4588        }
4589    }
4590
4591    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4592        IBinder threadBinder = thread.asBinder();
4593        // Find the application record.
4594        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4595            ProcessRecord rec = mLruProcesses.get(i);
4596            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4597                return i;
4598            }
4599        }
4600        return -1;
4601    }
4602
4603    final ProcessRecord getRecordForAppLocked(
4604            IApplicationThread thread) {
4605        if (thread == null) {
4606            return null;
4607        }
4608
4609        int appIndex = getLRURecordIndexForAppLocked(thread);
4610        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4611    }
4612
4613    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4614        // If there are no longer any background processes running,
4615        // and the app that died was not running instrumentation,
4616        // then tell everyone we are now low on memory.
4617        boolean haveBg = false;
4618        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4619            ProcessRecord rec = mLruProcesses.get(i);
4620            if (rec.thread != null
4621                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4622                haveBg = true;
4623                break;
4624            }
4625        }
4626
4627        if (!haveBg) {
4628            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4629            if (doReport) {
4630                long now = SystemClock.uptimeMillis();
4631                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4632                    doReport = false;
4633                } else {
4634                    mLastMemUsageReportTime = now;
4635                }
4636            }
4637            final ArrayList<ProcessMemInfo> memInfos
4638                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4639            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4640            long now = SystemClock.uptimeMillis();
4641            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4642                ProcessRecord rec = mLruProcesses.get(i);
4643                if (rec == dyingProc || rec.thread == null) {
4644                    continue;
4645                }
4646                if (doReport) {
4647                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4648                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4649                }
4650                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4651                    // The low memory report is overriding any current
4652                    // state for a GC request.  Make sure to do
4653                    // heavy/important/visible/foreground processes first.
4654                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4655                        rec.lastRequestedGc = 0;
4656                    } else {
4657                        rec.lastRequestedGc = rec.lastLowMemory;
4658                    }
4659                    rec.reportLowMemory = true;
4660                    rec.lastLowMemory = now;
4661                    mProcessesToGc.remove(rec);
4662                    addProcessToGcListLocked(rec);
4663                }
4664            }
4665            if (doReport) {
4666                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4667                mHandler.sendMessage(msg);
4668            }
4669            scheduleAppGcsLocked();
4670        }
4671    }
4672
4673    final void appDiedLocked(ProcessRecord app) {
4674       appDiedLocked(app, app.pid, app.thread);
4675    }
4676
4677    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4678        // First check if this ProcessRecord is actually active for the pid.
4679        synchronized (mPidsSelfLocked) {
4680            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4681            if (curProc != app) {
4682                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4683                return;
4684            }
4685        }
4686
4687        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4688        synchronized (stats) {
4689            stats.noteProcessDiedLocked(app.info.uid, pid);
4690        }
4691
4692        if (!app.killed) {
4693            Process.killProcessQuiet(pid);
4694            Process.killProcessGroup(app.info.uid, pid);
4695            app.killed = true;
4696        }
4697
4698        // Clean up already done if the process has been re-started.
4699        if (app.pid == pid && app.thread != null &&
4700                app.thread.asBinder() == thread.asBinder()) {
4701            boolean doLowMem = app.instrumentationClass == null;
4702            boolean doOomAdj = doLowMem;
4703            if (!app.killedByAm) {
4704                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4705                        + ") has died");
4706                mAllowLowerMemLevel = true;
4707            } else {
4708                // Note that we always want to do oom adj to update our state with the
4709                // new number of procs.
4710                mAllowLowerMemLevel = false;
4711                doLowMem = false;
4712            }
4713            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4714            if (DEBUG_CLEANUP) Slog.v(
4715                TAG, "Dying app: " + app + ", pid: " + pid
4716                + ", thread: " + thread.asBinder());
4717            handleAppDiedLocked(app, false, true);
4718
4719            if (doOomAdj) {
4720                updateOomAdjLocked();
4721            }
4722            if (doLowMem) {
4723                doLowMemReportIfNeededLocked(app);
4724            }
4725        } else if (app.pid != pid) {
4726            // A new process has already been started.
4727            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4728                    + ") has died and restarted (pid " + app.pid + ").");
4729            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4730        } else if (DEBUG_PROCESSES) {
4731            Slog.d(TAG, "Received spurious death notification for thread "
4732                    + thread.asBinder());
4733        }
4734    }
4735
4736    /**
4737     * If a stack trace dump file is configured, dump process stack traces.
4738     * @param clearTraces causes the dump file to be erased prior to the new
4739     *    traces being written, if true; when false, the new traces will be
4740     *    appended to any existing file content.
4741     * @param firstPids of dalvik VM processes to dump stack traces for first
4742     * @param lastPids of dalvik VM processes to dump stack traces for last
4743     * @param nativeProcs optional list of native process names to dump stack crawls
4744     * @return file containing stack traces, or null if no dump file is configured
4745     */
4746    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4747            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4748        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4749        if (tracesPath == null || tracesPath.length() == 0) {
4750            return null;
4751        }
4752
4753        File tracesFile = new File(tracesPath);
4754        try {
4755            File tracesDir = tracesFile.getParentFile();
4756            if (!tracesDir.exists()) {
4757                tracesDir.mkdirs();
4758                if (!SELinux.restorecon(tracesDir)) {
4759                    return null;
4760                }
4761            }
4762            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4763
4764            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4765            tracesFile.createNewFile();
4766            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4767        } catch (IOException e) {
4768            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4769            return null;
4770        }
4771
4772        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4773        return tracesFile;
4774    }
4775
4776    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4777            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4778        // Use a FileObserver to detect when traces finish writing.
4779        // The order of traces is considered important to maintain for legibility.
4780        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4781            @Override
4782            public synchronized void onEvent(int event, String path) { notify(); }
4783        };
4784
4785        try {
4786            observer.startWatching();
4787
4788            // First collect all of the stacks of the most important pids.
4789            if (firstPids != null) {
4790                try {
4791                    int num = firstPids.size();
4792                    for (int i = 0; i < num; i++) {
4793                        synchronized (observer) {
4794                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4795                            observer.wait(200);  // Wait for write-close, give up after 200msec
4796                        }
4797                    }
4798                } catch (InterruptedException e) {
4799                    Slog.wtf(TAG, e);
4800                }
4801            }
4802
4803            // Next collect the stacks of the native pids
4804            if (nativeProcs != null) {
4805                int[] pids = Process.getPidsForCommands(nativeProcs);
4806                if (pids != null) {
4807                    for (int pid : pids) {
4808                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4809                    }
4810                }
4811            }
4812
4813            // Lastly, measure CPU usage.
4814            if (processCpuTracker != null) {
4815                processCpuTracker.init();
4816                System.gc();
4817                processCpuTracker.update();
4818                try {
4819                    synchronized (processCpuTracker) {
4820                        processCpuTracker.wait(500); // measure over 1/2 second.
4821                    }
4822                } catch (InterruptedException e) {
4823                }
4824                processCpuTracker.update();
4825
4826                // We'll take the stack crawls of just the top apps using CPU.
4827                final int N = processCpuTracker.countWorkingStats();
4828                int numProcs = 0;
4829                for (int i=0; i<N && numProcs<5; i++) {
4830                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4831                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4832                        numProcs++;
4833                        try {
4834                            synchronized (observer) {
4835                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4836                                observer.wait(200);  // Wait for write-close, give up after 200msec
4837                            }
4838                        } catch (InterruptedException e) {
4839                            Slog.wtf(TAG, e);
4840                        }
4841
4842                    }
4843                }
4844            }
4845        } finally {
4846            observer.stopWatching();
4847        }
4848    }
4849
4850    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4851        if (true || IS_USER_BUILD) {
4852            return;
4853        }
4854        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4855        if (tracesPath == null || tracesPath.length() == 0) {
4856            return;
4857        }
4858
4859        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4860        StrictMode.allowThreadDiskWrites();
4861        try {
4862            final File tracesFile = new File(tracesPath);
4863            final File tracesDir = tracesFile.getParentFile();
4864            final File tracesTmp = new File(tracesDir, "__tmp__");
4865            try {
4866                if (!tracesDir.exists()) {
4867                    tracesDir.mkdirs();
4868                    if (!SELinux.restorecon(tracesDir.getPath())) {
4869                        return;
4870                    }
4871                }
4872                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4873
4874                if (tracesFile.exists()) {
4875                    tracesTmp.delete();
4876                    tracesFile.renameTo(tracesTmp);
4877                }
4878                StringBuilder sb = new StringBuilder();
4879                Time tobj = new Time();
4880                tobj.set(System.currentTimeMillis());
4881                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4882                sb.append(": ");
4883                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4884                sb.append(" since ");
4885                sb.append(msg);
4886                FileOutputStream fos = new FileOutputStream(tracesFile);
4887                fos.write(sb.toString().getBytes());
4888                if (app == null) {
4889                    fos.write("\n*** No application process!".getBytes());
4890                }
4891                fos.close();
4892                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4893            } catch (IOException e) {
4894                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4895                return;
4896            }
4897
4898            if (app != null) {
4899                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4900                firstPids.add(app.pid);
4901                dumpStackTraces(tracesPath, firstPids, null, null, null);
4902            }
4903
4904            File lastTracesFile = null;
4905            File curTracesFile = null;
4906            for (int i=9; i>=0; i--) {
4907                String name = String.format(Locale.US, "slow%02d.txt", i);
4908                curTracesFile = new File(tracesDir, name);
4909                if (curTracesFile.exists()) {
4910                    if (lastTracesFile != null) {
4911                        curTracesFile.renameTo(lastTracesFile);
4912                    } else {
4913                        curTracesFile.delete();
4914                    }
4915                }
4916                lastTracesFile = curTracesFile;
4917            }
4918            tracesFile.renameTo(curTracesFile);
4919            if (tracesTmp.exists()) {
4920                tracesTmp.renameTo(tracesFile);
4921            }
4922        } finally {
4923            StrictMode.setThreadPolicy(oldPolicy);
4924        }
4925    }
4926
4927    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4928            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4929        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4930        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4931
4932        if (mController != null) {
4933            try {
4934                // 0 == continue, -1 = kill process immediately
4935                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4936                if (res < 0 && app.pid != MY_PID) {
4937                    app.kill("anr", true);
4938                }
4939            } catch (RemoteException e) {
4940                mController = null;
4941                Watchdog.getInstance().setActivityController(null);
4942            }
4943        }
4944
4945        long anrTime = SystemClock.uptimeMillis();
4946        if (MONITOR_CPU_USAGE) {
4947            updateCpuStatsNow();
4948        }
4949
4950        synchronized (this) {
4951            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4952            if (mShuttingDown) {
4953                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4954                return;
4955            } else if (app.notResponding) {
4956                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4957                return;
4958            } else if (app.crashing) {
4959                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4960                return;
4961            }
4962
4963            // In case we come through here for the same app before completing
4964            // this one, mark as anring now so we will bail out.
4965            app.notResponding = true;
4966
4967            // Log the ANR to the event log.
4968            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4969                    app.processName, app.info.flags, annotation);
4970
4971            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4972            firstPids.add(app.pid);
4973
4974            int parentPid = app.pid;
4975            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4976            if (parentPid != app.pid) firstPids.add(parentPid);
4977
4978            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4979
4980            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4981                ProcessRecord r = mLruProcesses.get(i);
4982                if (r != null && r.thread != null) {
4983                    int pid = r.pid;
4984                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4985                        if (r.persistent) {
4986                            firstPids.add(pid);
4987                        } else {
4988                            lastPids.put(pid, Boolean.TRUE);
4989                        }
4990                    }
4991                }
4992            }
4993        }
4994
4995        // Log the ANR to the main log.
4996        StringBuilder info = new StringBuilder();
4997        info.setLength(0);
4998        info.append("ANR in ").append(app.processName);
4999        if (activity != null && activity.shortComponentName != null) {
5000            info.append(" (").append(activity.shortComponentName).append(")");
5001        }
5002        info.append("\n");
5003        info.append("PID: ").append(app.pid).append("\n");
5004        if (annotation != null) {
5005            info.append("Reason: ").append(annotation).append("\n");
5006        }
5007        if (parent != null && parent != activity) {
5008            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5009        }
5010
5011        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5012
5013        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5014                NATIVE_STACKS_OF_INTEREST);
5015
5016        String cpuInfo = null;
5017        if (MONITOR_CPU_USAGE) {
5018            updateCpuStatsNow();
5019            synchronized (mProcessCpuTracker) {
5020                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5021            }
5022            info.append(processCpuTracker.printCurrentLoad());
5023            info.append(cpuInfo);
5024        }
5025
5026        info.append(processCpuTracker.printCurrentState(anrTime));
5027
5028        Slog.e(TAG, info.toString());
5029        if (tracesFile == null) {
5030            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5031            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5032        }
5033
5034        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5035                cpuInfo, tracesFile, null);
5036
5037        if (mController != null) {
5038            try {
5039                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5040                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5041                if (res != 0) {
5042                    if (res < 0 && app.pid != MY_PID) {
5043                        app.kill("anr", true);
5044                    } else {
5045                        synchronized (this) {
5046                            mServices.scheduleServiceTimeoutLocked(app);
5047                        }
5048                    }
5049                    return;
5050                }
5051            } catch (RemoteException e) {
5052                mController = null;
5053                Watchdog.getInstance().setActivityController(null);
5054            }
5055        }
5056
5057        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5058        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5059                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5060
5061        synchronized (this) {
5062            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5063
5064            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5065                app.kill("bg anr", true);
5066                return;
5067            }
5068
5069            // Set the app's notResponding state, and look up the errorReportReceiver
5070            makeAppNotRespondingLocked(app,
5071                    activity != null ? activity.shortComponentName : null,
5072                    annotation != null ? "ANR " + annotation : "ANR",
5073                    info.toString());
5074
5075            // Bring up the infamous App Not Responding dialog
5076            Message msg = Message.obtain();
5077            HashMap<String, Object> map = new HashMap<String, Object>();
5078            msg.what = SHOW_NOT_RESPONDING_MSG;
5079            msg.obj = map;
5080            msg.arg1 = aboveSystem ? 1 : 0;
5081            map.put("app", app);
5082            if (activity != null) {
5083                map.put("activity", activity);
5084            }
5085
5086            mHandler.sendMessage(msg);
5087        }
5088    }
5089
5090    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5091        if (!mLaunchWarningShown) {
5092            mLaunchWarningShown = true;
5093            mHandler.post(new Runnable() {
5094                @Override
5095                public void run() {
5096                    synchronized (ActivityManagerService.this) {
5097                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5098                        d.show();
5099                        mHandler.postDelayed(new Runnable() {
5100                            @Override
5101                            public void run() {
5102                                synchronized (ActivityManagerService.this) {
5103                                    d.dismiss();
5104                                    mLaunchWarningShown = false;
5105                                }
5106                            }
5107                        }, 4000);
5108                    }
5109                }
5110            });
5111        }
5112    }
5113
5114    @Override
5115    public boolean clearApplicationUserData(final String packageName,
5116            final IPackageDataObserver observer, int userId) {
5117        enforceNotIsolatedCaller("clearApplicationUserData");
5118        int uid = Binder.getCallingUid();
5119        int pid = Binder.getCallingPid();
5120        userId = handleIncomingUser(pid, uid,
5121                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5122        long callingId = Binder.clearCallingIdentity();
5123        try {
5124            IPackageManager pm = AppGlobals.getPackageManager();
5125            int pkgUid = -1;
5126            synchronized(this) {
5127                try {
5128                    pkgUid = pm.getPackageUid(packageName, userId);
5129                } catch (RemoteException e) {
5130                }
5131                if (pkgUid == -1) {
5132                    Slog.w(TAG, "Invalid packageName: " + packageName);
5133                    if (observer != null) {
5134                        try {
5135                            observer.onRemoveCompleted(packageName, false);
5136                        } catch (RemoteException e) {
5137                            Slog.i(TAG, "Observer no longer exists.");
5138                        }
5139                    }
5140                    return false;
5141                }
5142                if (uid == pkgUid || checkComponentPermission(
5143                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5144                        pid, uid, -1, true)
5145                        == PackageManager.PERMISSION_GRANTED) {
5146                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5147                } else {
5148                    throw new SecurityException("PID " + pid + " does not have permission "
5149                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5150                                    + " of package " + packageName);
5151                }
5152
5153                // Remove all tasks match the cleared application package and user
5154                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5155                    final TaskRecord tr = mRecentTasks.get(i);
5156                    final String taskPackageName =
5157                            tr.getBaseIntent().getComponent().getPackageName();
5158                    if (tr.userId != userId) continue;
5159                    if (!taskPackageName.equals(packageName)) continue;
5160                    removeTaskByIdLocked(tr.taskId, false);
5161                }
5162            }
5163
5164            try {
5165                // Clear application user data
5166                pm.clearApplicationUserData(packageName, observer, userId);
5167
5168                synchronized(this) {
5169                    // Remove all permissions granted from/to this package
5170                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5171                }
5172
5173                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5174                        Uri.fromParts("package", packageName, null));
5175                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5176                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5177                        null, null, 0, null, null, null, false, false, userId);
5178            } catch (RemoteException e) {
5179            }
5180        } finally {
5181            Binder.restoreCallingIdentity(callingId);
5182        }
5183        return true;
5184    }
5185
5186    @Override
5187    public void killBackgroundProcesses(final String packageName, int userId) {
5188        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5189                != PackageManager.PERMISSION_GRANTED &&
5190                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5191                        != PackageManager.PERMISSION_GRANTED) {
5192            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5193                    + Binder.getCallingPid()
5194                    + ", uid=" + Binder.getCallingUid()
5195                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5196            Slog.w(TAG, msg);
5197            throw new SecurityException(msg);
5198        }
5199
5200        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5201                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5202        long callingId = Binder.clearCallingIdentity();
5203        try {
5204            IPackageManager pm = AppGlobals.getPackageManager();
5205            synchronized(this) {
5206                int appId = -1;
5207                try {
5208                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5209                } catch (RemoteException e) {
5210                }
5211                if (appId == -1) {
5212                    Slog.w(TAG, "Invalid packageName: " + packageName);
5213                    return;
5214                }
5215                killPackageProcessesLocked(packageName, appId, userId,
5216                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5217            }
5218        } finally {
5219            Binder.restoreCallingIdentity(callingId);
5220        }
5221    }
5222
5223    @Override
5224    public void killAllBackgroundProcesses() {
5225        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5226                != PackageManager.PERMISSION_GRANTED) {
5227            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5228                    + Binder.getCallingPid()
5229                    + ", uid=" + Binder.getCallingUid()
5230                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5231            Slog.w(TAG, msg);
5232            throw new SecurityException(msg);
5233        }
5234
5235        long callingId = Binder.clearCallingIdentity();
5236        try {
5237            synchronized(this) {
5238                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5239                final int NP = mProcessNames.getMap().size();
5240                for (int ip=0; ip<NP; ip++) {
5241                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5242                    final int NA = apps.size();
5243                    for (int ia=0; ia<NA; ia++) {
5244                        ProcessRecord app = apps.valueAt(ia);
5245                        if (app.persistent) {
5246                            // we don't kill persistent processes
5247                            continue;
5248                        }
5249                        if (app.removed) {
5250                            procs.add(app);
5251                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5252                            app.removed = true;
5253                            procs.add(app);
5254                        }
5255                    }
5256                }
5257
5258                int N = procs.size();
5259                for (int i=0; i<N; i++) {
5260                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5261                }
5262                mAllowLowerMemLevel = true;
5263                updateOomAdjLocked();
5264                doLowMemReportIfNeededLocked(null);
5265            }
5266        } finally {
5267            Binder.restoreCallingIdentity(callingId);
5268        }
5269    }
5270
5271    @Override
5272    public void forceStopPackage(final String packageName, int userId) {
5273        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5274                != PackageManager.PERMISSION_GRANTED) {
5275            String msg = "Permission Denial: forceStopPackage() from pid="
5276                    + Binder.getCallingPid()
5277                    + ", uid=" + Binder.getCallingUid()
5278                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5279            Slog.w(TAG, msg);
5280            throw new SecurityException(msg);
5281        }
5282        final int callingPid = Binder.getCallingPid();
5283        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5284                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5285        long callingId = Binder.clearCallingIdentity();
5286        try {
5287            IPackageManager pm = AppGlobals.getPackageManager();
5288            synchronized(this) {
5289                int[] users = userId == UserHandle.USER_ALL
5290                        ? getUsersLocked() : new int[] { userId };
5291                for (int user : users) {
5292                    int pkgUid = -1;
5293                    try {
5294                        pkgUid = pm.getPackageUid(packageName, user);
5295                    } catch (RemoteException e) {
5296                    }
5297                    if (pkgUid == -1) {
5298                        Slog.w(TAG, "Invalid packageName: " + packageName);
5299                        continue;
5300                    }
5301                    try {
5302                        pm.setPackageStoppedState(packageName, true, user);
5303                    } catch (RemoteException e) {
5304                    } catch (IllegalArgumentException e) {
5305                        Slog.w(TAG, "Failed trying to unstop package "
5306                                + packageName + ": " + e);
5307                    }
5308                    if (isUserRunningLocked(user, false)) {
5309                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5310                    }
5311                }
5312            }
5313        } finally {
5314            Binder.restoreCallingIdentity(callingId);
5315        }
5316    }
5317
5318    @Override
5319    public void addPackageDependency(String packageName) {
5320        synchronized (this) {
5321            int callingPid = Binder.getCallingPid();
5322            if (callingPid == Process.myPid()) {
5323                //  Yeah, um, no.
5324                return;
5325            }
5326            ProcessRecord proc;
5327            synchronized (mPidsSelfLocked) {
5328                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5329            }
5330            if (proc != null) {
5331                if (proc.pkgDeps == null) {
5332                    proc.pkgDeps = new ArraySet<String>(1);
5333                }
5334                proc.pkgDeps.add(packageName);
5335            }
5336        }
5337    }
5338
5339    /*
5340     * The pkg name and app id have to be specified.
5341     */
5342    @Override
5343    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5344        if (pkg == null) {
5345            return;
5346        }
5347        // Make sure the uid is valid.
5348        if (appid < 0) {
5349            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5350            return;
5351        }
5352        int callerUid = Binder.getCallingUid();
5353        // Only the system server can kill an application
5354        if (callerUid == Process.SYSTEM_UID) {
5355            // Post an aysnc message to kill the application
5356            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5357            msg.arg1 = appid;
5358            msg.arg2 = 0;
5359            Bundle bundle = new Bundle();
5360            bundle.putString("pkg", pkg);
5361            bundle.putString("reason", reason);
5362            msg.obj = bundle;
5363            mHandler.sendMessage(msg);
5364        } else {
5365            throw new SecurityException(callerUid + " cannot kill pkg: " +
5366                    pkg);
5367        }
5368    }
5369
5370    @Override
5371    public void closeSystemDialogs(String reason) {
5372        enforceNotIsolatedCaller("closeSystemDialogs");
5373
5374        final int pid = Binder.getCallingPid();
5375        final int uid = Binder.getCallingUid();
5376        final long origId = Binder.clearCallingIdentity();
5377        try {
5378            synchronized (this) {
5379                // Only allow this from foreground processes, so that background
5380                // applications can't abuse it to prevent system UI from being shown.
5381                if (uid >= Process.FIRST_APPLICATION_UID) {
5382                    ProcessRecord proc;
5383                    synchronized (mPidsSelfLocked) {
5384                        proc = mPidsSelfLocked.get(pid);
5385                    }
5386                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5387                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5388                                + " from background process " + proc);
5389                        return;
5390                    }
5391                }
5392                closeSystemDialogsLocked(reason);
5393            }
5394        } finally {
5395            Binder.restoreCallingIdentity(origId);
5396        }
5397    }
5398
5399    void closeSystemDialogsLocked(String reason) {
5400        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5401        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5402                | Intent.FLAG_RECEIVER_FOREGROUND);
5403        if (reason != null) {
5404            intent.putExtra("reason", reason);
5405        }
5406        mWindowManager.closeSystemDialogs(reason);
5407
5408        mStackSupervisor.closeSystemDialogsLocked();
5409
5410        broadcastIntentLocked(null, null, intent, null,
5411                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5412                Process.SYSTEM_UID, UserHandle.USER_ALL);
5413    }
5414
5415    @Override
5416    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5417        enforceNotIsolatedCaller("getProcessMemoryInfo");
5418        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5419        for (int i=pids.length-1; i>=0; i--) {
5420            ProcessRecord proc;
5421            int oomAdj;
5422            synchronized (this) {
5423                synchronized (mPidsSelfLocked) {
5424                    proc = mPidsSelfLocked.get(pids[i]);
5425                    oomAdj = proc != null ? proc.setAdj : 0;
5426                }
5427            }
5428            infos[i] = new Debug.MemoryInfo();
5429            Debug.getMemoryInfo(pids[i], infos[i]);
5430            if (proc != null) {
5431                synchronized (this) {
5432                    if (proc.thread != null && proc.setAdj == oomAdj) {
5433                        // Record this for posterity if the process has been stable.
5434                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5435                                infos[i].getTotalUss(), false, proc.pkgList);
5436                    }
5437                }
5438            }
5439        }
5440        return infos;
5441    }
5442
5443    @Override
5444    public long[] getProcessPss(int[] pids) {
5445        enforceNotIsolatedCaller("getProcessPss");
5446        long[] pss = new long[pids.length];
5447        for (int i=pids.length-1; i>=0; i--) {
5448            ProcessRecord proc;
5449            int oomAdj;
5450            synchronized (this) {
5451                synchronized (mPidsSelfLocked) {
5452                    proc = mPidsSelfLocked.get(pids[i]);
5453                    oomAdj = proc != null ? proc.setAdj : 0;
5454                }
5455            }
5456            long[] tmpUss = new long[1];
5457            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5458            if (proc != null) {
5459                synchronized (this) {
5460                    if (proc.thread != null && proc.setAdj == oomAdj) {
5461                        // Record this for posterity if the process has been stable.
5462                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5463                    }
5464                }
5465            }
5466        }
5467        return pss;
5468    }
5469
5470    @Override
5471    public void killApplicationProcess(String processName, int uid) {
5472        if (processName == null) {
5473            return;
5474        }
5475
5476        int callerUid = Binder.getCallingUid();
5477        // Only the system server can kill an application
5478        if (callerUid == Process.SYSTEM_UID) {
5479            synchronized (this) {
5480                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5481                if (app != null && app.thread != null) {
5482                    try {
5483                        app.thread.scheduleSuicide();
5484                    } catch (RemoteException e) {
5485                        // If the other end already died, then our work here is done.
5486                    }
5487                } else {
5488                    Slog.w(TAG, "Process/uid not found attempting kill of "
5489                            + processName + " / " + uid);
5490                }
5491            }
5492        } else {
5493            throw new SecurityException(callerUid + " cannot kill app process: " +
5494                    processName);
5495        }
5496    }
5497
5498    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5499        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5500                false, true, false, false, UserHandle.getUserId(uid), reason);
5501        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5502                Uri.fromParts("package", packageName, null));
5503        if (!mProcessesReady) {
5504            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5505                    | Intent.FLAG_RECEIVER_FOREGROUND);
5506        }
5507        intent.putExtra(Intent.EXTRA_UID, uid);
5508        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5509        broadcastIntentLocked(null, null, intent,
5510                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5511                false, false,
5512                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5513    }
5514
5515    private void forceStopUserLocked(int userId, String reason) {
5516        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5517        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5518        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5519                | Intent.FLAG_RECEIVER_FOREGROUND);
5520        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5521        broadcastIntentLocked(null, null, intent,
5522                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5523                false, false,
5524                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5525    }
5526
5527    private final boolean killPackageProcessesLocked(String packageName, int appId,
5528            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5529            boolean doit, boolean evenPersistent, String reason) {
5530        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5531
5532        // Remove all processes this package may have touched: all with the
5533        // same UID (except for the system or root user), and all whose name
5534        // matches the package name.
5535        final int NP = mProcessNames.getMap().size();
5536        for (int ip=0; ip<NP; ip++) {
5537            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5538            final int NA = apps.size();
5539            for (int ia=0; ia<NA; ia++) {
5540                ProcessRecord app = apps.valueAt(ia);
5541                if (app.persistent && !evenPersistent) {
5542                    // we don't kill persistent processes
5543                    continue;
5544                }
5545                if (app.removed) {
5546                    if (doit) {
5547                        procs.add(app);
5548                    }
5549                    continue;
5550                }
5551
5552                // Skip process if it doesn't meet our oom adj requirement.
5553                if (app.setAdj < minOomAdj) {
5554                    continue;
5555                }
5556
5557                // If no package is specified, we call all processes under the
5558                // give user id.
5559                if (packageName == null) {
5560                    if (app.userId != userId) {
5561                        continue;
5562                    }
5563                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5564                        continue;
5565                    }
5566                // Package has been specified, we want to hit all processes
5567                // that match it.  We need to qualify this by the processes
5568                // that are running under the specified app and user ID.
5569                } else {
5570                    final boolean isDep = app.pkgDeps != null
5571                            && app.pkgDeps.contains(packageName);
5572                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5573                        continue;
5574                    }
5575                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5576                        continue;
5577                    }
5578                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5579                        continue;
5580                    }
5581                }
5582
5583                // Process has passed all conditions, kill it!
5584                if (!doit) {
5585                    return true;
5586                }
5587                app.removed = true;
5588                procs.add(app);
5589            }
5590        }
5591
5592        int N = procs.size();
5593        for (int i=0; i<N; i++) {
5594            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5595        }
5596        updateOomAdjLocked();
5597        return N > 0;
5598    }
5599
5600    private final boolean forceStopPackageLocked(String name, int appId,
5601            boolean callerWillRestart, boolean purgeCache, boolean doit,
5602            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5603        int i;
5604        int N;
5605
5606        if (userId == UserHandle.USER_ALL && name == null) {
5607            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5608        }
5609
5610        if (appId < 0 && name != null) {
5611            try {
5612                appId = UserHandle.getAppId(
5613                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5614            } catch (RemoteException e) {
5615            }
5616        }
5617
5618        if (doit) {
5619            if (name != null) {
5620                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5621                        + " user=" + userId + ": " + reason);
5622            } else {
5623                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5624            }
5625
5626            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5627            for (int ip=pmap.size()-1; ip>=0; ip--) {
5628                SparseArray<Long> ba = pmap.valueAt(ip);
5629                for (i=ba.size()-1; i>=0; i--) {
5630                    boolean remove = false;
5631                    final int entUid = ba.keyAt(i);
5632                    if (name != null) {
5633                        if (userId == UserHandle.USER_ALL) {
5634                            if (UserHandle.getAppId(entUid) == appId) {
5635                                remove = true;
5636                            }
5637                        } else {
5638                            if (entUid == UserHandle.getUid(userId, appId)) {
5639                                remove = true;
5640                            }
5641                        }
5642                    } else if (UserHandle.getUserId(entUid) == userId) {
5643                        remove = true;
5644                    }
5645                    if (remove) {
5646                        ba.removeAt(i);
5647                    }
5648                }
5649                if (ba.size() == 0) {
5650                    pmap.removeAt(ip);
5651                }
5652            }
5653        }
5654
5655        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5656                -100, callerWillRestart, true, doit, evenPersistent,
5657                name == null ? ("stop user " + userId) : ("stop " + name));
5658
5659        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5660            if (!doit) {
5661                return true;
5662            }
5663            didSomething = true;
5664        }
5665
5666        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5667            if (!doit) {
5668                return true;
5669            }
5670            didSomething = true;
5671        }
5672
5673        if (name == null) {
5674            // Remove all sticky broadcasts from this user.
5675            mStickyBroadcasts.remove(userId);
5676        }
5677
5678        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5679        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5680                userId, providers)) {
5681            if (!doit) {
5682                return true;
5683            }
5684            didSomething = true;
5685        }
5686        N = providers.size();
5687        for (i=0; i<N; i++) {
5688            removeDyingProviderLocked(null, providers.get(i), true);
5689        }
5690
5691        // Remove transient permissions granted from/to this package/user
5692        removeUriPermissionsForPackageLocked(name, userId, false);
5693
5694        if (name == null || uninstalling) {
5695            // Remove pending intents.  For now we only do this when force
5696            // stopping users, because we have some problems when doing this
5697            // for packages -- app widgets are not currently cleaned up for
5698            // such packages, so they can be left with bad pending intents.
5699            if (mIntentSenderRecords.size() > 0) {
5700                Iterator<WeakReference<PendingIntentRecord>> it
5701                        = mIntentSenderRecords.values().iterator();
5702                while (it.hasNext()) {
5703                    WeakReference<PendingIntentRecord> wpir = it.next();
5704                    if (wpir == null) {
5705                        it.remove();
5706                        continue;
5707                    }
5708                    PendingIntentRecord pir = wpir.get();
5709                    if (pir == null) {
5710                        it.remove();
5711                        continue;
5712                    }
5713                    if (name == null) {
5714                        // Stopping user, remove all objects for the user.
5715                        if (pir.key.userId != userId) {
5716                            // Not the same user, skip it.
5717                            continue;
5718                        }
5719                    } else {
5720                        if (UserHandle.getAppId(pir.uid) != appId) {
5721                            // Different app id, skip it.
5722                            continue;
5723                        }
5724                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5725                            // Different user, skip it.
5726                            continue;
5727                        }
5728                        if (!pir.key.packageName.equals(name)) {
5729                            // Different package, skip it.
5730                            continue;
5731                        }
5732                    }
5733                    if (!doit) {
5734                        return true;
5735                    }
5736                    didSomething = true;
5737                    it.remove();
5738                    pir.canceled = true;
5739                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5740                        pir.key.activity.pendingResults.remove(pir.ref);
5741                    }
5742                }
5743            }
5744        }
5745
5746        if (doit) {
5747            if (purgeCache && name != null) {
5748                AttributeCache ac = AttributeCache.instance();
5749                if (ac != null) {
5750                    ac.removePackage(name);
5751                }
5752            }
5753            if (mBooted) {
5754                mStackSupervisor.resumeTopActivitiesLocked();
5755                mStackSupervisor.scheduleIdleLocked();
5756            }
5757        }
5758
5759        return didSomething;
5760    }
5761
5762    private final boolean removeProcessLocked(ProcessRecord app,
5763            boolean callerWillRestart, boolean allowRestart, String reason) {
5764        final String name = app.processName;
5765        final int uid = app.uid;
5766        if (DEBUG_PROCESSES) Slog.d(
5767            TAG, "Force removing proc " + app.toShortString() + " (" + name
5768            + "/" + uid + ")");
5769
5770        mProcessNames.remove(name, uid);
5771        mIsolatedProcesses.remove(app.uid);
5772        if (mHeavyWeightProcess == app) {
5773            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5774                    mHeavyWeightProcess.userId, 0));
5775            mHeavyWeightProcess = null;
5776        }
5777        boolean needRestart = false;
5778        if (app.pid > 0 && app.pid != MY_PID) {
5779            int pid = app.pid;
5780            synchronized (mPidsSelfLocked) {
5781                mPidsSelfLocked.remove(pid);
5782                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5783            }
5784            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5785            if (app.isolated) {
5786                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5787            }
5788            app.kill(reason, true);
5789            handleAppDiedLocked(app, true, allowRestart);
5790            removeLruProcessLocked(app);
5791
5792            if (app.persistent && !app.isolated) {
5793                if (!callerWillRestart) {
5794                    addAppLocked(app.info, false, null /* ABI override */);
5795                } else {
5796                    needRestart = true;
5797                }
5798            }
5799        } else {
5800            mRemovedProcesses.add(app);
5801        }
5802
5803        return needRestart;
5804    }
5805
5806    private final void processStartTimedOutLocked(ProcessRecord app) {
5807        final int pid = app.pid;
5808        boolean gone = false;
5809        synchronized (mPidsSelfLocked) {
5810            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5811            if (knownApp != null && knownApp.thread == null) {
5812                mPidsSelfLocked.remove(pid);
5813                gone = true;
5814            }
5815        }
5816
5817        if (gone) {
5818            Slog.w(TAG, "Process " + app + " failed to attach");
5819            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5820                    pid, app.uid, app.processName);
5821            mProcessNames.remove(app.processName, app.uid);
5822            mIsolatedProcesses.remove(app.uid);
5823            if (mHeavyWeightProcess == app) {
5824                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5825                        mHeavyWeightProcess.userId, 0));
5826                mHeavyWeightProcess = null;
5827            }
5828            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5829            if (app.isolated) {
5830                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5831            }
5832            // Take care of any launching providers waiting for this process.
5833            checkAppInLaunchingProvidersLocked(app, true);
5834            // Take care of any services that are waiting for the process.
5835            mServices.processStartTimedOutLocked(app);
5836            app.kill("start timeout", true);
5837            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5838                Slog.w(TAG, "Unattached app died before backup, skipping");
5839                try {
5840                    IBackupManager bm = IBackupManager.Stub.asInterface(
5841                            ServiceManager.getService(Context.BACKUP_SERVICE));
5842                    bm.agentDisconnected(app.info.packageName);
5843                } catch (RemoteException e) {
5844                    // Can't happen; the backup manager is local
5845                }
5846            }
5847            if (isPendingBroadcastProcessLocked(pid)) {
5848                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5849                skipPendingBroadcastLocked(pid);
5850            }
5851        } else {
5852            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5853        }
5854    }
5855
5856    private final boolean attachApplicationLocked(IApplicationThread thread,
5857            int pid) {
5858
5859        // Find the application record that is being attached...  either via
5860        // the pid if we are running in multiple processes, or just pull the
5861        // next app record if we are emulating process with anonymous threads.
5862        ProcessRecord app;
5863        if (pid != MY_PID && pid >= 0) {
5864            synchronized (mPidsSelfLocked) {
5865                app = mPidsSelfLocked.get(pid);
5866            }
5867        } else {
5868            app = null;
5869        }
5870
5871        if (app == null) {
5872            Slog.w(TAG, "No pending application record for pid " + pid
5873                    + " (IApplicationThread " + thread + "); dropping process");
5874            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5875            if (pid > 0 && pid != MY_PID) {
5876                Process.killProcessQuiet(pid);
5877                //TODO: Process.killProcessGroup(app.info.uid, pid);
5878            } else {
5879                try {
5880                    thread.scheduleExit();
5881                } catch (Exception e) {
5882                    // Ignore exceptions.
5883                }
5884            }
5885            return false;
5886        }
5887
5888        // If this application record is still attached to a previous
5889        // process, clean it up now.
5890        if (app.thread != null) {
5891            handleAppDiedLocked(app, true, true);
5892        }
5893
5894        // Tell the process all about itself.
5895
5896        if (localLOGV) Slog.v(
5897                TAG, "Binding process pid " + pid + " to record " + app);
5898
5899        final String processName = app.processName;
5900        try {
5901            AppDeathRecipient adr = new AppDeathRecipient(
5902                    app, pid, thread);
5903            thread.asBinder().linkToDeath(adr, 0);
5904            app.deathRecipient = adr;
5905        } catch (RemoteException e) {
5906            app.resetPackageList(mProcessStats);
5907            startProcessLocked(app, "link fail", processName);
5908            return false;
5909        }
5910
5911        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5912
5913        app.makeActive(thread, mProcessStats);
5914        app.curAdj = app.setAdj = -100;
5915        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5916        app.forcingToForeground = null;
5917        updateProcessForegroundLocked(app, false, false);
5918        app.hasShownUi = false;
5919        app.debugging = false;
5920        app.cached = false;
5921        app.killedByAm = false;
5922
5923        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5924
5925        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5926        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5927
5928        if (!normalMode) {
5929            Slog.i(TAG, "Launching preboot mode app: " + app);
5930        }
5931
5932        if (localLOGV) Slog.v(
5933            TAG, "New app record " + app
5934            + " thread=" + thread.asBinder() + " pid=" + pid);
5935        try {
5936            int testMode = IApplicationThread.DEBUG_OFF;
5937            if (mDebugApp != null && mDebugApp.equals(processName)) {
5938                testMode = mWaitForDebugger
5939                    ? IApplicationThread.DEBUG_WAIT
5940                    : IApplicationThread.DEBUG_ON;
5941                app.debugging = true;
5942                if (mDebugTransient) {
5943                    mDebugApp = mOrigDebugApp;
5944                    mWaitForDebugger = mOrigWaitForDebugger;
5945                }
5946            }
5947            String profileFile = app.instrumentationProfileFile;
5948            ParcelFileDescriptor profileFd = null;
5949            int samplingInterval = 0;
5950            boolean profileAutoStop = false;
5951            if (mProfileApp != null && mProfileApp.equals(processName)) {
5952                mProfileProc = app;
5953                profileFile = mProfileFile;
5954                profileFd = mProfileFd;
5955                samplingInterval = mSamplingInterval;
5956                profileAutoStop = mAutoStopProfiler;
5957            }
5958            boolean enableOpenGlTrace = false;
5959            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5960                enableOpenGlTrace = true;
5961                mOpenGlTraceApp = null;
5962            }
5963
5964            // If the app is being launched for restore or full backup, set it up specially
5965            boolean isRestrictedBackupMode = false;
5966            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5967                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5968                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5969                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5970            }
5971
5972            ensurePackageDexOpt(app.instrumentationInfo != null
5973                    ? app.instrumentationInfo.packageName
5974                    : app.info.packageName);
5975            if (app.instrumentationClass != null) {
5976                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5977            }
5978            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5979                    + processName + " with config " + mConfiguration);
5980            ApplicationInfo appInfo = app.instrumentationInfo != null
5981                    ? app.instrumentationInfo : app.info;
5982            app.compat = compatibilityInfoForPackageLocked(appInfo);
5983            if (profileFd != null) {
5984                profileFd = profileFd.dup();
5985            }
5986            ProfilerInfo profilerInfo = profileFile == null ? null
5987                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5988            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5989                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5990                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5991                    isRestrictedBackupMode || !normalMode, app.persistent,
5992                    new Configuration(mConfiguration), app.compat,
5993                    getCommonServicesLocked(app.isolated),
5994                    mCoreSettingsObserver.getCoreSettingsLocked());
5995            updateLruProcessLocked(app, false, null);
5996            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5997        } catch (Exception e) {
5998            // todo: Yikes!  What should we do?  For now we will try to
5999            // start another process, but that could easily get us in
6000            // an infinite loop of restarting processes...
6001            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6002
6003            app.resetPackageList(mProcessStats);
6004            app.unlinkDeathRecipient();
6005            startProcessLocked(app, "bind fail", processName);
6006            return false;
6007        }
6008
6009        // Remove this record from the list of starting applications.
6010        mPersistentStartingProcesses.remove(app);
6011        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6012                "Attach application locked removing on hold: " + app);
6013        mProcessesOnHold.remove(app);
6014
6015        boolean badApp = false;
6016        boolean didSomething = false;
6017
6018        // See if the top visible activity is waiting to run in this process...
6019        if (normalMode) {
6020            try {
6021                if (mStackSupervisor.attachApplicationLocked(app)) {
6022                    didSomething = true;
6023                }
6024            } catch (Exception e) {
6025                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6026                badApp = true;
6027            }
6028        }
6029
6030        // Find any services that should be running in this process...
6031        if (!badApp) {
6032            try {
6033                didSomething |= mServices.attachApplicationLocked(app, processName);
6034            } catch (Exception e) {
6035                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6036                badApp = true;
6037            }
6038        }
6039
6040        // Check if a next-broadcast receiver is in this process...
6041        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6042            try {
6043                didSomething |= sendPendingBroadcastsLocked(app);
6044            } catch (Exception e) {
6045                // If the app died trying to launch the receiver we declare it 'bad'
6046                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6047                badApp = true;
6048            }
6049        }
6050
6051        // Check whether the next backup agent is in this process...
6052        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6053            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6054            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6055            try {
6056                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6057                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6058                        mBackupTarget.backupMode);
6059            } catch (Exception e) {
6060                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6061                badApp = true;
6062            }
6063        }
6064
6065        if (badApp) {
6066            app.kill("error during init", true);
6067            handleAppDiedLocked(app, false, true);
6068            return false;
6069        }
6070
6071        if (!didSomething) {
6072            updateOomAdjLocked();
6073        }
6074
6075        return true;
6076    }
6077
6078    @Override
6079    public final void attachApplication(IApplicationThread thread) {
6080        synchronized (this) {
6081            int callingPid = Binder.getCallingPid();
6082            final long origId = Binder.clearCallingIdentity();
6083            attachApplicationLocked(thread, callingPid);
6084            Binder.restoreCallingIdentity(origId);
6085        }
6086    }
6087
6088    @Override
6089    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6090        final long origId = Binder.clearCallingIdentity();
6091        synchronized (this) {
6092            ActivityStack stack = ActivityRecord.getStackLocked(token);
6093            if (stack != null) {
6094                ActivityRecord r =
6095                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6096                if (stopProfiling) {
6097                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6098                        try {
6099                            mProfileFd.close();
6100                        } catch (IOException e) {
6101                        }
6102                        clearProfilerLocked();
6103                    }
6104                }
6105            }
6106        }
6107        Binder.restoreCallingIdentity(origId);
6108    }
6109
6110    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6111        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6112                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6113    }
6114
6115    void enableScreenAfterBoot() {
6116        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6117                SystemClock.uptimeMillis());
6118        mWindowManager.enableScreenAfterBoot();
6119
6120        synchronized (this) {
6121            updateEventDispatchingLocked();
6122        }
6123    }
6124
6125    @Override
6126    public void showBootMessage(final CharSequence msg, final boolean always) {
6127        enforceNotIsolatedCaller("showBootMessage");
6128        mWindowManager.showBootMessage(msg, always);
6129    }
6130
6131    @Override
6132    public void keyguardWaitingForActivityDrawn() {
6133        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6134        final long token = Binder.clearCallingIdentity();
6135        try {
6136            synchronized (this) {
6137                if (DEBUG_LOCKSCREEN) logLockScreen("");
6138                mWindowManager.keyguardWaitingForActivityDrawn();
6139                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6140                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6141                    updateSleepIfNeededLocked();
6142                }
6143            }
6144        } finally {
6145            Binder.restoreCallingIdentity(token);
6146        }
6147    }
6148
6149    final void finishBooting() {
6150        synchronized (this) {
6151            if (!mBootAnimationComplete) {
6152                mCallFinishBooting = true;
6153                return;
6154            }
6155            mCallFinishBooting = false;
6156        }
6157
6158        ArraySet<String> completedIsas = new ArraySet<String>();
6159        for (String abi : Build.SUPPORTED_ABIS) {
6160            Process.establishZygoteConnectionForAbi(abi);
6161            final String instructionSet = VMRuntime.getInstructionSet(abi);
6162            if (!completedIsas.contains(instructionSet)) {
6163                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6164                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6165                }
6166                completedIsas.add(instructionSet);
6167            }
6168        }
6169
6170        IntentFilter pkgFilter = new IntentFilter();
6171        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6172        pkgFilter.addDataScheme("package");
6173        mContext.registerReceiver(new BroadcastReceiver() {
6174            @Override
6175            public void onReceive(Context context, Intent intent) {
6176                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6177                if (pkgs != null) {
6178                    for (String pkg : pkgs) {
6179                        synchronized (ActivityManagerService.this) {
6180                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6181                                    0, "finished booting")) {
6182                                setResultCode(Activity.RESULT_OK);
6183                                return;
6184                            }
6185                        }
6186                    }
6187                }
6188            }
6189        }, pkgFilter);
6190
6191        // Let system services know.
6192        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6193
6194        synchronized (this) {
6195            // Ensure that any processes we had put on hold are now started
6196            // up.
6197            final int NP = mProcessesOnHold.size();
6198            if (NP > 0) {
6199                ArrayList<ProcessRecord> procs =
6200                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6201                for (int ip=0; ip<NP; ip++) {
6202                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6203                            + procs.get(ip));
6204                    startProcessLocked(procs.get(ip), "on-hold", null);
6205                }
6206            }
6207
6208            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6209                // Start looking for apps that are abusing wake locks.
6210                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6211                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6212                // Tell anyone interested that we are done booting!
6213                SystemProperties.set("sys.boot_completed", "1");
6214
6215                // And trigger dev.bootcomplete if we are not showing encryption progress
6216                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6217                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6218                    SystemProperties.set("dev.bootcomplete", "1");
6219                }
6220                for (int i=0; i<mStartedUsers.size(); i++) {
6221                    UserStartedState uss = mStartedUsers.valueAt(i);
6222                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6223                        uss.mState = UserStartedState.STATE_RUNNING;
6224                        final int userId = mStartedUsers.keyAt(i);
6225                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6226                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6227                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6228                        broadcastIntentLocked(null, null, intent, null,
6229                                new IIntentReceiver.Stub() {
6230                                    @Override
6231                                    public void performReceive(Intent intent, int resultCode,
6232                                            String data, Bundle extras, boolean ordered,
6233                                            boolean sticky, int sendingUser) {
6234                                        synchronized (ActivityManagerService.this) {
6235                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6236                                                    true, false);
6237                                        }
6238                                    }
6239                                },
6240                                0, null, null,
6241                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6242                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6243                                userId);
6244                    }
6245                }
6246                scheduleStartProfilesLocked();
6247            }
6248        }
6249    }
6250
6251    @Override
6252    public void bootAnimationComplete() {
6253        final boolean callFinishBooting;
6254        synchronized (this) {
6255            callFinishBooting = mCallFinishBooting;
6256            mBootAnimationComplete = true;
6257        }
6258        if (callFinishBooting) {
6259            finishBooting();
6260        }
6261    }
6262
6263    @Override
6264    public void systemBackupRestored() {
6265        synchronized (this) {
6266            if (mSystemReady) {
6267                mTaskPersister.restoreTasksFromOtherDeviceLocked();
6268            } else {
6269                Slog.w(TAG, "System backup restored before system is ready");
6270            }
6271        }
6272    }
6273
6274    final void ensureBootCompleted() {
6275        boolean booting;
6276        boolean enableScreen;
6277        synchronized (this) {
6278            booting = mBooting;
6279            mBooting = false;
6280            enableScreen = !mBooted;
6281            mBooted = true;
6282        }
6283
6284        if (booting) {
6285            finishBooting();
6286        }
6287
6288        if (enableScreen) {
6289            enableScreenAfterBoot();
6290        }
6291    }
6292
6293    @Override
6294    public final void activityResumed(IBinder token) {
6295        final long origId = Binder.clearCallingIdentity();
6296        synchronized(this) {
6297            ActivityStack stack = ActivityRecord.getStackLocked(token);
6298            if (stack != null) {
6299                ActivityRecord.activityResumedLocked(token);
6300            }
6301        }
6302        Binder.restoreCallingIdentity(origId);
6303    }
6304
6305    @Override
6306    public final void activityPaused(IBinder token) {
6307        final long origId = Binder.clearCallingIdentity();
6308        synchronized(this) {
6309            ActivityStack stack = ActivityRecord.getStackLocked(token);
6310            if (stack != null) {
6311                stack.activityPausedLocked(token, false);
6312            }
6313        }
6314        Binder.restoreCallingIdentity(origId);
6315    }
6316
6317    @Override
6318    public final void activityStopped(IBinder token, Bundle icicle,
6319            PersistableBundle persistentState, CharSequence description) {
6320        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6321
6322        // Refuse possible leaked file descriptors
6323        if (icicle != null && icicle.hasFileDescriptors()) {
6324            throw new IllegalArgumentException("File descriptors passed in Bundle");
6325        }
6326
6327        final long origId = Binder.clearCallingIdentity();
6328
6329        synchronized (this) {
6330            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6331            if (r != null) {
6332                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6333            }
6334        }
6335
6336        trimApplications();
6337
6338        Binder.restoreCallingIdentity(origId);
6339    }
6340
6341    @Override
6342    public final void activityDestroyed(IBinder token) {
6343        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6344        synchronized (this) {
6345            ActivityStack stack = ActivityRecord.getStackLocked(token);
6346            if (stack != null) {
6347                stack.activityDestroyedLocked(token, "activityDestroyed");
6348            }
6349        }
6350    }
6351
6352    @Override
6353    public final void backgroundResourcesReleased(IBinder token) {
6354        final long origId = Binder.clearCallingIdentity();
6355        try {
6356            synchronized (this) {
6357                ActivityStack stack = ActivityRecord.getStackLocked(token);
6358                if (stack != null) {
6359                    stack.backgroundResourcesReleased();
6360                }
6361            }
6362        } finally {
6363            Binder.restoreCallingIdentity(origId);
6364        }
6365    }
6366
6367    @Override
6368    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6369        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6370    }
6371
6372    @Override
6373    public final void notifyEnterAnimationComplete(IBinder token) {
6374        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6375    }
6376
6377    @Override
6378    public String getCallingPackage(IBinder token) {
6379        synchronized (this) {
6380            ActivityRecord r = getCallingRecordLocked(token);
6381            return r != null ? r.info.packageName : null;
6382        }
6383    }
6384
6385    @Override
6386    public ComponentName getCallingActivity(IBinder token) {
6387        synchronized (this) {
6388            ActivityRecord r = getCallingRecordLocked(token);
6389            return r != null ? r.intent.getComponent() : null;
6390        }
6391    }
6392
6393    private ActivityRecord getCallingRecordLocked(IBinder token) {
6394        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6395        if (r == null) {
6396            return null;
6397        }
6398        return r.resultTo;
6399    }
6400
6401    @Override
6402    public ComponentName getActivityClassForToken(IBinder token) {
6403        synchronized(this) {
6404            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6405            if (r == null) {
6406                return null;
6407            }
6408            return r.intent.getComponent();
6409        }
6410    }
6411
6412    @Override
6413    public String getPackageForToken(IBinder token) {
6414        synchronized(this) {
6415            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6416            if (r == null) {
6417                return null;
6418            }
6419            return r.packageName;
6420        }
6421    }
6422
6423    @Override
6424    public IIntentSender getIntentSender(int type,
6425            String packageName, IBinder token, String resultWho,
6426            int requestCode, Intent[] intents, String[] resolvedTypes,
6427            int flags, Bundle options, int userId) {
6428        enforceNotIsolatedCaller("getIntentSender");
6429        // Refuse possible leaked file descriptors
6430        if (intents != null) {
6431            if (intents.length < 1) {
6432                throw new IllegalArgumentException("Intents array length must be >= 1");
6433            }
6434            for (int i=0; i<intents.length; i++) {
6435                Intent intent = intents[i];
6436                if (intent != null) {
6437                    if (intent.hasFileDescriptors()) {
6438                        throw new IllegalArgumentException("File descriptors passed in Intent");
6439                    }
6440                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6441                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6442                        throw new IllegalArgumentException(
6443                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6444                    }
6445                    intents[i] = new Intent(intent);
6446                }
6447            }
6448            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6449                throw new IllegalArgumentException(
6450                        "Intent array length does not match resolvedTypes length");
6451            }
6452        }
6453        if (options != null) {
6454            if (options.hasFileDescriptors()) {
6455                throw new IllegalArgumentException("File descriptors passed in options");
6456            }
6457        }
6458
6459        synchronized(this) {
6460            int callingUid = Binder.getCallingUid();
6461            int origUserId = userId;
6462            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6463                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6464                    ALLOW_NON_FULL, "getIntentSender", null);
6465            if (origUserId == UserHandle.USER_CURRENT) {
6466                // We don't want to evaluate this until the pending intent is
6467                // actually executed.  However, we do want to always do the
6468                // security checking for it above.
6469                userId = UserHandle.USER_CURRENT;
6470            }
6471            try {
6472                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6473                    int uid = AppGlobals.getPackageManager()
6474                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6475                    if (!UserHandle.isSameApp(callingUid, uid)) {
6476                        String msg = "Permission Denial: getIntentSender() from pid="
6477                            + Binder.getCallingPid()
6478                            + ", uid=" + Binder.getCallingUid()
6479                            + ", (need uid=" + uid + ")"
6480                            + " is not allowed to send as package " + packageName;
6481                        Slog.w(TAG, msg);
6482                        throw new SecurityException(msg);
6483                    }
6484                }
6485
6486                return getIntentSenderLocked(type, packageName, callingUid, userId,
6487                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6488
6489            } catch (RemoteException e) {
6490                throw new SecurityException(e);
6491            }
6492        }
6493    }
6494
6495    IIntentSender getIntentSenderLocked(int type, String packageName,
6496            int callingUid, int userId, IBinder token, String resultWho,
6497            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6498            Bundle options) {
6499        if (DEBUG_MU)
6500            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6501        ActivityRecord activity = null;
6502        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6503            activity = ActivityRecord.isInStackLocked(token);
6504            if (activity == null) {
6505                return null;
6506            }
6507            if (activity.finishing) {
6508                return null;
6509            }
6510        }
6511
6512        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6513        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6514        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6515        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6516                |PendingIntent.FLAG_UPDATE_CURRENT);
6517
6518        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6519                type, packageName, activity, resultWho,
6520                requestCode, intents, resolvedTypes, flags, options, userId);
6521        WeakReference<PendingIntentRecord> ref;
6522        ref = mIntentSenderRecords.get(key);
6523        PendingIntentRecord rec = ref != null ? ref.get() : null;
6524        if (rec != null) {
6525            if (!cancelCurrent) {
6526                if (updateCurrent) {
6527                    if (rec.key.requestIntent != null) {
6528                        rec.key.requestIntent.replaceExtras(intents != null ?
6529                                intents[intents.length - 1] : null);
6530                    }
6531                    if (intents != null) {
6532                        intents[intents.length-1] = rec.key.requestIntent;
6533                        rec.key.allIntents = intents;
6534                        rec.key.allResolvedTypes = resolvedTypes;
6535                    } else {
6536                        rec.key.allIntents = null;
6537                        rec.key.allResolvedTypes = null;
6538                    }
6539                }
6540                return rec;
6541            }
6542            rec.canceled = true;
6543            mIntentSenderRecords.remove(key);
6544        }
6545        if (noCreate) {
6546            return rec;
6547        }
6548        rec = new PendingIntentRecord(this, key, callingUid);
6549        mIntentSenderRecords.put(key, rec.ref);
6550        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6551            if (activity.pendingResults == null) {
6552                activity.pendingResults
6553                        = new HashSet<WeakReference<PendingIntentRecord>>();
6554            }
6555            activity.pendingResults.add(rec.ref);
6556        }
6557        return rec;
6558    }
6559
6560    @Override
6561    public void cancelIntentSender(IIntentSender sender) {
6562        if (!(sender instanceof PendingIntentRecord)) {
6563            return;
6564        }
6565        synchronized(this) {
6566            PendingIntentRecord rec = (PendingIntentRecord)sender;
6567            try {
6568                int uid = AppGlobals.getPackageManager()
6569                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6570                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6571                    String msg = "Permission Denial: cancelIntentSender() from pid="
6572                        + Binder.getCallingPid()
6573                        + ", uid=" + Binder.getCallingUid()
6574                        + " is not allowed to cancel packges "
6575                        + rec.key.packageName;
6576                    Slog.w(TAG, msg);
6577                    throw new SecurityException(msg);
6578                }
6579            } catch (RemoteException e) {
6580                throw new SecurityException(e);
6581            }
6582            cancelIntentSenderLocked(rec, true);
6583        }
6584    }
6585
6586    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6587        rec.canceled = true;
6588        mIntentSenderRecords.remove(rec.key);
6589        if (cleanActivity && rec.key.activity != null) {
6590            rec.key.activity.pendingResults.remove(rec.ref);
6591        }
6592    }
6593
6594    @Override
6595    public String getPackageForIntentSender(IIntentSender pendingResult) {
6596        if (!(pendingResult instanceof PendingIntentRecord)) {
6597            return null;
6598        }
6599        try {
6600            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6601            return res.key.packageName;
6602        } catch (ClassCastException e) {
6603        }
6604        return null;
6605    }
6606
6607    @Override
6608    public int getUidForIntentSender(IIntentSender sender) {
6609        if (sender instanceof PendingIntentRecord) {
6610            try {
6611                PendingIntentRecord res = (PendingIntentRecord)sender;
6612                return res.uid;
6613            } catch (ClassCastException e) {
6614            }
6615        }
6616        return -1;
6617    }
6618
6619    @Override
6620    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6621        if (!(pendingResult instanceof PendingIntentRecord)) {
6622            return false;
6623        }
6624        try {
6625            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6626            if (res.key.allIntents == null) {
6627                return false;
6628            }
6629            for (int i=0; i<res.key.allIntents.length; i++) {
6630                Intent intent = res.key.allIntents[i];
6631                if (intent.getPackage() != null && intent.getComponent() != null) {
6632                    return false;
6633                }
6634            }
6635            return true;
6636        } catch (ClassCastException e) {
6637        }
6638        return false;
6639    }
6640
6641    @Override
6642    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6643        if (!(pendingResult instanceof PendingIntentRecord)) {
6644            return false;
6645        }
6646        try {
6647            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6648            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6649                return true;
6650            }
6651            return false;
6652        } catch (ClassCastException e) {
6653        }
6654        return false;
6655    }
6656
6657    @Override
6658    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6659        if (!(pendingResult instanceof PendingIntentRecord)) {
6660            return null;
6661        }
6662        try {
6663            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6664            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6665        } catch (ClassCastException e) {
6666        }
6667        return null;
6668    }
6669
6670    @Override
6671    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6672        if (!(pendingResult instanceof PendingIntentRecord)) {
6673            return null;
6674        }
6675        try {
6676            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6677            Intent intent = res.key.requestIntent;
6678            if (intent != null) {
6679                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6680                        || res.lastTagPrefix.equals(prefix))) {
6681                    return res.lastTag;
6682                }
6683                res.lastTagPrefix = prefix;
6684                StringBuilder sb = new StringBuilder(128);
6685                if (prefix != null) {
6686                    sb.append(prefix);
6687                }
6688                if (intent.getAction() != null) {
6689                    sb.append(intent.getAction());
6690                } else if (intent.getComponent() != null) {
6691                    intent.getComponent().appendShortString(sb);
6692                } else {
6693                    sb.append("?");
6694                }
6695                return res.lastTag = sb.toString();
6696            }
6697        } catch (ClassCastException e) {
6698        }
6699        return null;
6700    }
6701
6702    @Override
6703    public void setProcessLimit(int max) {
6704        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6705                "setProcessLimit()");
6706        synchronized (this) {
6707            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6708            mProcessLimitOverride = max;
6709        }
6710        trimApplications();
6711    }
6712
6713    @Override
6714    public int getProcessLimit() {
6715        synchronized (this) {
6716            return mProcessLimitOverride;
6717        }
6718    }
6719
6720    void foregroundTokenDied(ForegroundToken token) {
6721        synchronized (ActivityManagerService.this) {
6722            synchronized (mPidsSelfLocked) {
6723                ForegroundToken cur
6724                    = mForegroundProcesses.get(token.pid);
6725                if (cur != token) {
6726                    return;
6727                }
6728                mForegroundProcesses.remove(token.pid);
6729                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6730                if (pr == null) {
6731                    return;
6732                }
6733                pr.forcingToForeground = null;
6734                updateProcessForegroundLocked(pr, false, false);
6735            }
6736            updateOomAdjLocked();
6737        }
6738    }
6739
6740    @Override
6741    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6742        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6743                "setProcessForeground()");
6744        synchronized(this) {
6745            boolean changed = false;
6746
6747            synchronized (mPidsSelfLocked) {
6748                ProcessRecord pr = mPidsSelfLocked.get(pid);
6749                if (pr == null && isForeground) {
6750                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6751                    return;
6752                }
6753                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6754                if (oldToken != null) {
6755                    oldToken.token.unlinkToDeath(oldToken, 0);
6756                    mForegroundProcesses.remove(pid);
6757                    if (pr != null) {
6758                        pr.forcingToForeground = null;
6759                    }
6760                    changed = true;
6761                }
6762                if (isForeground && token != null) {
6763                    ForegroundToken newToken = new ForegroundToken() {
6764                        @Override
6765                        public void binderDied() {
6766                            foregroundTokenDied(this);
6767                        }
6768                    };
6769                    newToken.pid = pid;
6770                    newToken.token = token;
6771                    try {
6772                        token.linkToDeath(newToken, 0);
6773                        mForegroundProcesses.put(pid, newToken);
6774                        pr.forcingToForeground = token;
6775                        changed = true;
6776                    } catch (RemoteException e) {
6777                        // If the process died while doing this, we will later
6778                        // do the cleanup with the process death link.
6779                    }
6780                }
6781            }
6782
6783            if (changed) {
6784                updateOomAdjLocked();
6785            }
6786        }
6787    }
6788
6789    // =========================================================
6790    // PERMISSIONS
6791    // =========================================================
6792
6793    static class PermissionController extends IPermissionController.Stub {
6794        ActivityManagerService mActivityManagerService;
6795        PermissionController(ActivityManagerService activityManagerService) {
6796            mActivityManagerService = activityManagerService;
6797        }
6798
6799        @Override
6800        public boolean checkPermission(String permission, int pid, int uid) {
6801            return mActivityManagerService.checkPermission(permission, pid,
6802                    uid) == PackageManager.PERMISSION_GRANTED;
6803        }
6804    }
6805
6806    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6807        @Override
6808        public int checkComponentPermission(String permission, int pid, int uid,
6809                int owningUid, boolean exported) {
6810            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6811                    owningUid, exported);
6812        }
6813
6814        @Override
6815        public Object getAMSLock() {
6816            return ActivityManagerService.this;
6817        }
6818    }
6819
6820    /**
6821     * This can be called with or without the global lock held.
6822     */
6823    int checkComponentPermission(String permission, int pid, int uid,
6824            int owningUid, boolean exported) {
6825        if (pid == MY_PID) {
6826            return PackageManager.PERMISSION_GRANTED;
6827        }
6828        return ActivityManager.checkComponentPermission(permission, uid,
6829                owningUid, exported);
6830    }
6831
6832    /**
6833     * As the only public entry point for permissions checking, this method
6834     * can enforce the semantic that requesting a check on a null global
6835     * permission is automatically denied.  (Internally a null permission
6836     * string is used when calling {@link #checkComponentPermission} in cases
6837     * when only uid-based security is needed.)
6838     *
6839     * This can be called with or without the global lock held.
6840     */
6841    @Override
6842    public int checkPermission(String permission, int pid, int uid) {
6843        if (permission == null) {
6844            return PackageManager.PERMISSION_DENIED;
6845        }
6846        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6847    }
6848
6849    @Override
6850    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6851        if (permission == null) {
6852            return PackageManager.PERMISSION_DENIED;
6853        }
6854
6855        // We might be performing an operation on behalf of an indirect binder
6856        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6857        // client identity accordingly before proceeding.
6858        Identity tlsIdentity = sCallerIdentity.get();
6859        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6860            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6861                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6862            uid = tlsIdentity.uid;
6863            pid = tlsIdentity.pid;
6864        }
6865
6866        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6867    }
6868
6869    /**
6870     * Binder IPC calls go through the public entry point.
6871     * This can be called with or without the global lock held.
6872     */
6873    int checkCallingPermission(String permission) {
6874        return checkPermission(permission,
6875                Binder.getCallingPid(),
6876                UserHandle.getAppId(Binder.getCallingUid()));
6877    }
6878
6879    /**
6880     * This can be called with or without the global lock held.
6881     */
6882    void enforceCallingPermission(String permission, String func) {
6883        if (checkCallingPermission(permission)
6884                == PackageManager.PERMISSION_GRANTED) {
6885            return;
6886        }
6887
6888        String msg = "Permission Denial: " + func + " from pid="
6889                + Binder.getCallingPid()
6890                + ", uid=" + Binder.getCallingUid()
6891                + " requires " + permission;
6892        Slog.w(TAG, msg);
6893        throw new SecurityException(msg);
6894    }
6895
6896    /**
6897     * Determine if UID is holding permissions required to access {@link Uri} in
6898     * the given {@link ProviderInfo}. Final permission checking is always done
6899     * in {@link ContentProvider}.
6900     */
6901    private final boolean checkHoldingPermissionsLocked(
6902            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6903        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6904                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6905        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6906            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6907                    != PERMISSION_GRANTED) {
6908                return false;
6909            }
6910        }
6911        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6912    }
6913
6914    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6915            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6916        if (pi.applicationInfo.uid == uid) {
6917            return true;
6918        } else if (!pi.exported) {
6919            return false;
6920        }
6921
6922        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6923        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6924        try {
6925            // check if target holds top-level <provider> permissions
6926            if (!readMet && pi.readPermission != null && considerUidPermissions
6927                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6928                readMet = true;
6929            }
6930            if (!writeMet && pi.writePermission != null && considerUidPermissions
6931                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6932                writeMet = true;
6933            }
6934
6935            // track if unprotected read/write is allowed; any denied
6936            // <path-permission> below removes this ability
6937            boolean allowDefaultRead = pi.readPermission == null;
6938            boolean allowDefaultWrite = pi.writePermission == null;
6939
6940            // check if target holds any <path-permission> that match uri
6941            final PathPermission[] pps = pi.pathPermissions;
6942            if (pps != null) {
6943                final String path = grantUri.uri.getPath();
6944                int i = pps.length;
6945                while (i > 0 && (!readMet || !writeMet)) {
6946                    i--;
6947                    PathPermission pp = pps[i];
6948                    if (pp.match(path)) {
6949                        if (!readMet) {
6950                            final String pprperm = pp.getReadPermission();
6951                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6952                                    + pprperm + " for " + pp.getPath()
6953                                    + ": match=" + pp.match(path)
6954                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6955                            if (pprperm != null) {
6956                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6957                                        == PERMISSION_GRANTED) {
6958                                    readMet = true;
6959                                } else {
6960                                    allowDefaultRead = false;
6961                                }
6962                            }
6963                        }
6964                        if (!writeMet) {
6965                            final String ppwperm = pp.getWritePermission();
6966                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6967                                    + ppwperm + " for " + pp.getPath()
6968                                    + ": match=" + pp.match(path)
6969                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6970                            if (ppwperm != null) {
6971                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6972                                        == PERMISSION_GRANTED) {
6973                                    writeMet = true;
6974                                } else {
6975                                    allowDefaultWrite = false;
6976                                }
6977                            }
6978                        }
6979                    }
6980                }
6981            }
6982
6983            // grant unprotected <provider> read/write, if not blocked by
6984            // <path-permission> above
6985            if (allowDefaultRead) readMet = true;
6986            if (allowDefaultWrite) writeMet = true;
6987
6988        } catch (RemoteException e) {
6989            return false;
6990        }
6991
6992        return readMet && writeMet;
6993    }
6994
6995    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6996        ProviderInfo pi = null;
6997        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6998        if (cpr != null) {
6999            pi = cpr.info;
7000        } else {
7001            try {
7002                pi = AppGlobals.getPackageManager().resolveContentProvider(
7003                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7004            } catch (RemoteException ex) {
7005            }
7006        }
7007        return pi;
7008    }
7009
7010    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7011        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7012        if (targetUris != null) {
7013            return targetUris.get(grantUri);
7014        }
7015        return null;
7016    }
7017
7018    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7019            String targetPkg, int targetUid, GrantUri grantUri) {
7020        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7021        if (targetUris == null) {
7022            targetUris = Maps.newArrayMap();
7023            mGrantedUriPermissions.put(targetUid, targetUris);
7024        }
7025
7026        UriPermission perm = targetUris.get(grantUri);
7027        if (perm == null) {
7028            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7029            targetUris.put(grantUri, perm);
7030        }
7031
7032        return perm;
7033    }
7034
7035    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7036            final int modeFlags) {
7037        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7038        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7039                : UriPermission.STRENGTH_OWNED;
7040
7041        // Root gets to do everything.
7042        if (uid == 0) {
7043            return true;
7044        }
7045
7046        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7047        if (perms == null) return false;
7048
7049        // First look for exact match
7050        final UriPermission exactPerm = perms.get(grantUri);
7051        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7052            return true;
7053        }
7054
7055        // No exact match, look for prefixes
7056        final int N = perms.size();
7057        for (int i = 0; i < N; i++) {
7058            final UriPermission perm = perms.valueAt(i);
7059            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7060                    && perm.getStrength(modeFlags) >= minStrength) {
7061                return true;
7062            }
7063        }
7064
7065        return false;
7066    }
7067
7068    /**
7069     * @param uri This uri must NOT contain an embedded userId.
7070     * @param userId The userId in which the uri is to be resolved.
7071     */
7072    @Override
7073    public int checkUriPermission(Uri uri, int pid, int uid,
7074            final int modeFlags, int userId, IBinder callerToken) {
7075        enforceNotIsolatedCaller("checkUriPermission");
7076
7077        // Another redirected-binder-call permissions check as in
7078        // {@link checkPermissionWithToken}.
7079        Identity tlsIdentity = sCallerIdentity.get();
7080        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7081            uid = tlsIdentity.uid;
7082            pid = tlsIdentity.pid;
7083        }
7084
7085        // Our own process gets to do everything.
7086        if (pid == MY_PID) {
7087            return PackageManager.PERMISSION_GRANTED;
7088        }
7089        synchronized (this) {
7090            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7091                    ? PackageManager.PERMISSION_GRANTED
7092                    : PackageManager.PERMISSION_DENIED;
7093        }
7094    }
7095
7096    /**
7097     * Check if the targetPkg can be granted permission to access uri by
7098     * the callingUid using the given modeFlags.  Throws a security exception
7099     * if callingUid is not allowed to do this.  Returns the uid of the target
7100     * if the URI permission grant should be performed; returns -1 if it is not
7101     * needed (for example targetPkg already has permission to access the URI).
7102     * If you already know the uid of the target, you can supply it in
7103     * lastTargetUid else set that to -1.
7104     */
7105    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7106            final int modeFlags, int lastTargetUid) {
7107        if (!Intent.isAccessUriMode(modeFlags)) {
7108            return -1;
7109        }
7110
7111        if (targetPkg != null) {
7112            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7113                    "Checking grant " + targetPkg + " permission to " + grantUri);
7114        }
7115
7116        final IPackageManager pm = AppGlobals.getPackageManager();
7117
7118        // If this is not a content: uri, we can't do anything with it.
7119        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7120            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7121                    "Can't grant URI permission for non-content URI: " + grantUri);
7122            return -1;
7123        }
7124
7125        final String authority = grantUri.uri.getAuthority();
7126        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7127        if (pi == null) {
7128            Slog.w(TAG, "No content provider found for permission check: " +
7129                    grantUri.uri.toSafeString());
7130            return -1;
7131        }
7132
7133        int targetUid = lastTargetUid;
7134        if (targetUid < 0 && targetPkg != null) {
7135            try {
7136                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7137                if (targetUid < 0) {
7138                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7139                            "Can't grant URI permission no uid for: " + targetPkg);
7140                    return -1;
7141                }
7142            } catch (RemoteException ex) {
7143                return -1;
7144            }
7145        }
7146
7147        if (targetUid >= 0) {
7148            // First...  does the target actually need this permission?
7149            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7150                // No need to grant the target this permission.
7151                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7152                        "Target " + targetPkg + " already has full permission to " + grantUri);
7153                return -1;
7154            }
7155        } else {
7156            // First...  there is no target package, so can anyone access it?
7157            boolean allowed = pi.exported;
7158            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7159                if (pi.readPermission != null) {
7160                    allowed = false;
7161                }
7162            }
7163            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7164                if (pi.writePermission != null) {
7165                    allowed = false;
7166                }
7167            }
7168            if (allowed) {
7169                return -1;
7170            }
7171        }
7172
7173        /* There is a special cross user grant if:
7174         * - The target is on another user.
7175         * - Apps on the current user can access the uri without any uid permissions.
7176         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7177         * grant uri permissions.
7178         */
7179        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7180                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7181                modeFlags, false /*without considering the uid permissions*/);
7182
7183        // Second...  is the provider allowing granting of URI permissions?
7184        if (!specialCrossUserGrant) {
7185            if (!pi.grantUriPermissions) {
7186                throw new SecurityException("Provider " + pi.packageName
7187                        + "/" + pi.name
7188                        + " does not allow granting of Uri permissions (uri "
7189                        + grantUri + ")");
7190            }
7191            if (pi.uriPermissionPatterns != null) {
7192                final int N = pi.uriPermissionPatterns.length;
7193                boolean allowed = false;
7194                for (int i=0; i<N; i++) {
7195                    if (pi.uriPermissionPatterns[i] != null
7196                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7197                        allowed = true;
7198                        break;
7199                    }
7200                }
7201                if (!allowed) {
7202                    throw new SecurityException("Provider " + pi.packageName
7203                            + "/" + pi.name
7204                            + " does not allow granting of permission to path of Uri "
7205                            + grantUri);
7206                }
7207            }
7208        }
7209
7210        // Third...  does the caller itself have permission to access
7211        // this uri?
7212        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7213            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7214                // Require they hold a strong enough Uri permission
7215                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7216                    throw new SecurityException("Uid " + callingUid
7217                            + " does not have permission to uri " + grantUri);
7218                }
7219            }
7220        }
7221        return targetUid;
7222    }
7223
7224    /**
7225     * @param uri This uri must NOT contain an embedded userId.
7226     * @param userId The userId in which the uri is to be resolved.
7227     */
7228    @Override
7229    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7230            final int modeFlags, int userId) {
7231        enforceNotIsolatedCaller("checkGrantUriPermission");
7232        synchronized(this) {
7233            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7234                    new GrantUri(userId, uri, false), modeFlags, -1);
7235        }
7236    }
7237
7238    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7239            final int modeFlags, UriPermissionOwner owner) {
7240        if (!Intent.isAccessUriMode(modeFlags)) {
7241            return;
7242        }
7243
7244        // So here we are: the caller has the assumed permission
7245        // to the uri, and the target doesn't.  Let's now give this to
7246        // the target.
7247
7248        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7249                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7250
7251        final String authority = grantUri.uri.getAuthority();
7252        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7253        if (pi == null) {
7254            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7255            return;
7256        }
7257
7258        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7259            grantUri.prefix = true;
7260        }
7261        final UriPermission perm = findOrCreateUriPermissionLocked(
7262                pi.packageName, targetPkg, targetUid, grantUri);
7263        perm.grantModes(modeFlags, owner);
7264    }
7265
7266    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7267            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7268        if (targetPkg == null) {
7269            throw new NullPointerException("targetPkg");
7270        }
7271        int targetUid;
7272        final IPackageManager pm = AppGlobals.getPackageManager();
7273        try {
7274            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7275        } catch (RemoteException ex) {
7276            return;
7277        }
7278
7279        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7280                targetUid);
7281        if (targetUid < 0) {
7282            return;
7283        }
7284
7285        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7286                owner);
7287    }
7288
7289    static class NeededUriGrants extends ArrayList<GrantUri> {
7290        final String targetPkg;
7291        final int targetUid;
7292        final int flags;
7293
7294        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7295            this.targetPkg = targetPkg;
7296            this.targetUid = targetUid;
7297            this.flags = flags;
7298        }
7299    }
7300
7301    /**
7302     * Like checkGrantUriPermissionLocked, but takes an Intent.
7303     */
7304    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7305            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7306        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7307                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7308                + " clip=" + (intent != null ? intent.getClipData() : null)
7309                + " from " + intent + "; flags=0x"
7310                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7311
7312        if (targetPkg == null) {
7313            throw new NullPointerException("targetPkg");
7314        }
7315
7316        if (intent == null) {
7317            return null;
7318        }
7319        Uri data = intent.getData();
7320        ClipData clip = intent.getClipData();
7321        if (data == null && clip == null) {
7322            return null;
7323        }
7324        // Default userId for uris in the intent (if they don't specify it themselves)
7325        int contentUserHint = intent.getContentUserHint();
7326        if (contentUserHint == UserHandle.USER_CURRENT) {
7327            contentUserHint = UserHandle.getUserId(callingUid);
7328        }
7329        final IPackageManager pm = AppGlobals.getPackageManager();
7330        int targetUid;
7331        if (needed != null) {
7332            targetUid = needed.targetUid;
7333        } else {
7334            try {
7335                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7336            } catch (RemoteException ex) {
7337                return null;
7338            }
7339            if (targetUid < 0) {
7340                if (DEBUG_URI_PERMISSION) {
7341                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7342                            + " on user " + targetUserId);
7343                }
7344                return null;
7345            }
7346        }
7347        if (data != null) {
7348            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7349            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7350                    targetUid);
7351            if (targetUid > 0) {
7352                if (needed == null) {
7353                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7354                }
7355                needed.add(grantUri);
7356            }
7357        }
7358        if (clip != null) {
7359            for (int i=0; i<clip.getItemCount(); i++) {
7360                Uri uri = clip.getItemAt(i).getUri();
7361                if (uri != null) {
7362                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7363                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7364                            targetUid);
7365                    if (targetUid > 0) {
7366                        if (needed == null) {
7367                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7368                        }
7369                        needed.add(grantUri);
7370                    }
7371                } else {
7372                    Intent clipIntent = clip.getItemAt(i).getIntent();
7373                    if (clipIntent != null) {
7374                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7375                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7376                        if (newNeeded != null) {
7377                            needed = newNeeded;
7378                        }
7379                    }
7380                }
7381            }
7382        }
7383
7384        return needed;
7385    }
7386
7387    /**
7388     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7389     */
7390    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7391            UriPermissionOwner owner) {
7392        if (needed != null) {
7393            for (int i=0; i<needed.size(); i++) {
7394                GrantUri grantUri = needed.get(i);
7395                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7396                        grantUri, needed.flags, owner);
7397            }
7398        }
7399    }
7400
7401    void grantUriPermissionFromIntentLocked(int callingUid,
7402            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7403        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7404                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7405        if (needed == null) {
7406            return;
7407        }
7408
7409        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7410    }
7411
7412    /**
7413     * @param uri This uri must NOT contain an embedded userId.
7414     * @param userId The userId in which the uri is to be resolved.
7415     */
7416    @Override
7417    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7418            final int modeFlags, int userId) {
7419        enforceNotIsolatedCaller("grantUriPermission");
7420        GrantUri grantUri = new GrantUri(userId, uri, false);
7421        synchronized(this) {
7422            final ProcessRecord r = getRecordForAppLocked(caller);
7423            if (r == null) {
7424                throw new SecurityException("Unable to find app for caller "
7425                        + caller
7426                        + " when granting permission to uri " + grantUri);
7427            }
7428            if (targetPkg == null) {
7429                throw new IllegalArgumentException("null target");
7430            }
7431            if (grantUri == null) {
7432                throw new IllegalArgumentException("null uri");
7433            }
7434
7435            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7436                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7437                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7438                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7439
7440            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7441                    UserHandle.getUserId(r.uid));
7442        }
7443    }
7444
7445    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7446        if (perm.modeFlags == 0) {
7447            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7448                    perm.targetUid);
7449            if (perms != null) {
7450                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7451                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7452
7453                perms.remove(perm.uri);
7454                if (perms.isEmpty()) {
7455                    mGrantedUriPermissions.remove(perm.targetUid);
7456                }
7457            }
7458        }
7459    }
7460
7461    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7462        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7463
7464        final IPackageManager pm = AppGlobals.getPackageManager();
7465        final String authority = grantUri.uri.getAuthority();
7466        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7467        if (pi == null) {
7468            Slog.w(TAG, "No content provider found for permission revoke: "
7469                    + grantUri.toSafeString());
7470            return;
7471        }
7472
7473        // Does the caller have this permission on the URI?
7474        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7475            // If they don't have direct access to the URI, then revoke any
7476            // ownerless URI permissions that have been granted to them.
7477            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7478            if (perms != null) {
7479                boolean persistChanged = false;
7480                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7481                    final UriPermission perm = it.next();
7482                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7483                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7484                        if (DEBUG_URI_PERMISSION)
7485                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7486                                    " permission to " + perm.uri);
7487                        persistChanged |= perm.revokeModes(
7488                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7489                        if (perm.modeFlags == 0) {
7490                            it.remove();
7491                        }
7492                    }
7493                }
7494                if (perms.isEmpty()) {
7495                    mGrantedUriPermissions.remove(callingUid);
7496                }
7497                if (persistChanged) {
7498                    schedulePersistUriGrants();
7499                }
7500            }
7501            return;
7502        }
7503
7504        boolean persistChanged = false;
7505
7506        // Go through all of the permissions and remove any that match.
7507        int N = mGrantedUriPermissions.size();
7508        for (int i = 0; i < N; i++) {
7509            final int targetUid = mGrantedUriPermissions.keyAt(i);
7510            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7511
7512            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7513                final UriPermission perm = it.next();
7514                if (perm.uri.sourceUserId == grantUri.sourceUserId
7515                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7516                    if (DEBUG_URI_PERMISSION)
7517                        Slog.v(TAG,
7518                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7519                    persistChanged |= perm.revokeModes(
7520                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7521                    if (perm.modeFlags == 0) {
7522                        it.remove();
7523                    }
7524                }
7525            }
7526
7527            if (perms.isEmpty()) {
7528                mGrantedUriPermissions.remove(targetUid);
7529                N--;
7530                i--;
7531            }
7532        }
7533
7534        if (persistChanged) {
7535            schedulePersistUriGrants();
7536        }
7537    }
7538
7539    /**
7540     * @param uri This uri must NOT contain an embedded userId.
7541     * @param userId The userId in which the uri is to be resolved.
7542     */
7543    @Override
7544    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7545            int userId) {
7546        enforceNotIsolatedCaller("revokeUriPermission");
7547        synchronized(this) {
7548            final ProcessRecord r = getRecordForAppLocked(caller);
7549            if (r == null) {
7550                throw new SecurityException("Unable to find app for caller "
7551                        + caller
7552                        + " when revoking permission to uri " + uri);
7553            }
7554            if (uri == null) {
7555                Slog.w(TAG, "revokeUriPermission: null uri");
7556                return;
7557            }
7558
7559            if (!Intent.isAccessUriMode(modeFlags)) {
7560                return;
7561            }
7562
7563            final IPackageManager pm = AppGlobals.getPackageManager();
7564            final String authority = uri.getAuthority();
7565            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7566            if (pi == null) {
7567                Slog.w(TAG, "No content provider found for permission revoke: "
7568                        + uri.toSafeString());
7569                return;
7570            }
7571
7572            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7573        }
7574    }
7575
7576    /**
7577     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7578     * given package.
7579     *
7580     * @param packageName Package name to match, or {@code null} to apply to all
7581     *            packages.
7582     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7583     *            to all users.
7584     * @param persistable If persistable grants should be removed.
7585     */
7586    private void removeUriPermissionsForPackageLocked(
7587            String packageName, int userHandle, boolean persistable) {
7588        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7589            throw new IllegalArgumentException("Must narrow by either package or user");
7590        }
7591
7592        boolean persistChanged = false;
7593
7594        int N = mGrantedUriPermissions.size();
7595        for (int i = 0; i < N; i++) {
7596            final int targetUid = mGrantedUriPermissions.keyAt(i);
7597            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7598
7599            // Only inspect grants matching user
7600            if (userHandle == UserHandle.USER_ALL
7601                    || userHandle == UserHandle.getUserId(targetUid)) {
7602                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7603                    final UriPermission perm = it.next();
7604
7605                    // Only inspect grants matching package
7606                    if (packageName == null || perm.sourcePkg.equals(packageName)
7607                            || perm.targetPkg.equals(packageName)) {
7608                        persistChanged |= perm.revokeModes(persistable
7609                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7610
7611                        // Only remove when no modes remain; any persisted grants
7612                        // will keep this alive.
7613                        if (perm.modeFlags == 0) {
7614                            it.remove();
7615                        }
7616                    }
7617                }
7618
7619                if (perms.isEmpty()) {
7620                    mGrantedUriPermissions.remove(targetUid);
7621                    N--;
7622                    i--;
7623                }
7624            }
7625        }
7626
7627        if (persistChanged) {
7628            schedulePersistUriGrants();
7629        }
7630    }
7631
7632    @Override
7633    public IBinder newUriPermissionOwner(String name) {
7634        enforceNotIsolatedCaller("newUriPermissionOwner");
7635        synchronized(this) {
7636            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7637            return owner.getExternalTokenLocked();
7638        }
7639    }
7640
7641    /**
7642     * @param uri This uri must NOT contain an embedded userId.
7643     * @param sourceUserId The userId in which the uri is to be resolved.
7644     * @param targetUserId The userId of the app that receives the grant.
7645     */
7646    @Override
7647    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7648            final int modeFlags, int sourceUserId, int targetUserId) {
7649        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7650                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7651        synchronized(this) {
7652            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7653            if (owner == null) {
7654                throw new IllegalArgumentException("Unknown owner: " + token);
7655            }
7656            if (fromUid != Binder.getCallingUid()) {
7657                if (Binder.getCallingUid() != Process.myUid()) {
7658                    // Only system code can grant URI permissions on behalf
7659                    // of other users.
7660                    throw new SecurityException("nice try");
7661                }
7662            }
7663            if (targetPkg == null) {
7664                throw new IllegalArgumentException("null target");
7665            }
7666            if (uri == null) {
7667                throw new IllegalArgumentException("null uri");
7668            }
7669
7670            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7671                    modeFlags, owner, targetUserId);
7672        }
7673    }
7674
7675    /**
7676     * @param uri This uri must NOT contain an embedded userId.
7677     * @param userId The userId in which the uri is to be resolved.
7678     */
7679    @Override
7680    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7681        synchronized(this) {
7682            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7683            if (owner == null) {
7684                throw new IllegalArgumentException("Unknown owner: " + token);
7685            }
7686
7687            if (uri == null) {
7688                owner.removeUriPermissionsLocked(mode);
7689            } else {
7690                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7691            }
7692        }
7693    }
7694
7695    private void schedulePersistUriGrants() {
7696        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7697            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7698                    10 * DateUtils.SECOND_IN_MILLIS);
7699        }
7700    }
7701
7702    private void writeGrantedUriPermissions() {
7703        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7704
7705        // Snapshot permissions so we can persist without lock
7706        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7707        synchronized (this) {
7708            final int size = mGrantedUriPermissions.size();
7709            for (int i = 0; i < size; i++) {
7710                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7711                for (UriPermission perm : perms.values()) {
7712                    if (perm.persistedModeFlags != 0) {
7713                        persist.add(perm.snapshot());
7714                    }
7715                }
7716            }
7717        }
7718
7719        FileOutputStream fos = null;
7720        try {
7721            fos = mGrantFile.startWrite();
7722
7723            XmlSerializer out = new FastXmlSerializer();
7724            out.setOutput(fos, "utf-8");
7725            out.startDocument(null, true);
7726            out.startTag(null, TAG_URI_GRANTS);
7727            for (UriPermission.Snapshot perm : persist) {
7728                out.startTag(null, TAG_URI_GRANT);
7729                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7730                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7731                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7732                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7733                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7734                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7735                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7736                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7737                out.endTag(null, TAG_URI_GRANT);
7738            }
7739            out.endTag(null, TAG_URI_GRANTS);
7740            out.endDocument();
7741
7742            mGrantFile.finishWrite(fos);
7743        } catch (IOException e) {
7744            if (fos != null) {
7745                mGrantFile.failWrite(fos);
7746            }
7747        }
7748    }
7749
7750    private void readGrantedUriPermissionsLocked() {
7751        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7752
7753        final long now = System.currentTimeMillis();
7754
7755        FileInputStream fis = null;
7756        try {
7757            fis = mGrantFile.openRead();
7758            final XmlPullParser in = Xml.newPullParser();
7759            in.setInput(fis, null);
7760
7761            int type;
7762            while ((type = in.next()) != END_DOCUMENT) {
7763                final String tag = in.getName();
7764                if (type == START_TAG) {
7765                    if (TAG_URI_GRANT.equals(tag)) {
7766                        final int sourceUserId;
7767                        final int targetUserId;
7768                        final int userHandle = readIntAttribute(in,
7769                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7770                        if (userHandle != UserHandle.USER_NULL) {
7771                            // For backwards compatibility.
7772                            sourceUserId = userHandle;
7773                            targetUserId = userHandle;
7774                        } else {
7775                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7776                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7777                        }
7778                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7779                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7780                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7781                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7782                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7783                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7784
7785                        // Sanity check that provider still belongs to source package
7786                        final ProviderInfo pi = getProviderInfoLocked(
7787                                uri.getAuthority(), sourceUserId);
7788                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7789                            int targetUid = -1;
7790                            try {
7791                                targetUid = AppGlobals.getPackageManager()
7792                                        .getPackageUid(targetPkg, targetUserId);
7793                            } catch (RemoteException e) {
7794                            }
7795                            if (targetUid != -1) {
7796                                final UriPermission perm = findOrCreateUriPermissionLocked(
7797                                        sourcePkg, targetPkg, targetUid,
7798                                        new GrantUri(sourceUserId, uri, prefix));
7799                                perm.initPersistedModes(modeFlags, createdTime);
7800                            }
7801                        } else {
7802                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7803                                    + " but instead found " + pi);
7804                        }
7805                    }
7806                }
7807            }
7808        } catch (FileNotFoundException e) {
7809            // Missing grants is okay
7810        } catch (IOException e) {
7811            Slog.wtf(TAG, "Failed reading Uri grants", e);
7812        } catch (XmlPullParserException e) {
7813            Slog.wtf(TAG, "Failed reading Uri grants", e);
7814        } finally {
7815            IoUtils.closeQuietly(fis);
7816        }
7817    }
7818
7819    /**
7820     * @param uri This uri must NOT contain an embedded userId.
7821     * @param userId The userId in which the uri is to be resolved.
7822     */
7823    @Override
7824    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7825        enforceNotIsolatedCaller("takePersistableUriPermission");
7826
7827        Preconditions.checkFlagsArgument(modeFlags,
7828                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7829
7830        synchronized (this) {
7831            final int callingUid = Binder.getCallingUid();
7832            boolean persistChanged = false;
7833            GrantUri grantUri = new GrantUri(userId, uri, false);
7834
7835            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7836                    new GrantUri(userId, uri, false));
7837            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7838                    new GrantUri(userId, uri, true));
7839
7840            final boolean exactValid = (exactPerm != null)
7841                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7842            final boolean prefixValid = (prefixPerm != null)
7843                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7844
7845            if (!(exactValid || prefixValid)) {
7846                throw new SecurityException("No persistable permission grants found for UID "
7847                        + callingUid + " and Uri " + grantUri.toSafeString());
7848            }
7849
7850            if (exactValid) {
7851                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7852            }
7853            if (prefixValid) {
7854                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7855            }
7856
7857            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7858
7859            if (persistChanged) {
7860                schedulePersistUriGrants();
7861            }
7862        }
7863    }
7864
7865    /**
7866     * @param uri This uri must NOT contain an embedded userId.
7867     * @param userId The userId in which the uri is to be resolved.
7868     */
7869    @Override
7870    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7871        enforceNotIsolatedCaller("releasePersistableUriPermission");
7872
7873        Preconditions.checkFlagsArgument(modeFlags,
7874                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7875
7876        synchronized (this) {
7877            final int callingUid = Binder.getCallingUid();
7878            boolean persistChanged = false;
7879
7880            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7881                    new GrantUri(userId, uri, false));
7882            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7883                    new GrantUri(userId, uri, true));
7884            if (exactPerm == null && prefixPerm == null) {
7885                throw new SecurityException("No permission grants found for UID " + callingUid
7886                        + " and Uri " + uri.toSafeString());
7887            }
7888
7889            if (exactPerm != null) {
7890                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7891                removeUriPermissionIfNeededLocked(exactPerm);
7892            }
7893            if (prefixPerm != null) {
7894                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7895                removeUriPermissionIfNeededLocked(prefixPerm);
7896            }
7897
7898            if (persistChanged) {
7899                schedulePersistUriGrants();
7900            }
7901        }
7902    }
7903
7904    /**
7905     * Prune any older {@link UriPermission} for the given UID until outstanding
7906     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7907     *
7908     * @return if any mutations occured that require persisting.
7909     */
7910    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7911        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7912        if (perms == null) return false;
7913        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7914
7915        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7916        for (UriPermission perm : perms.values()) {
7917            if (perm.persistedModeFlags != 0) {
7918                persisted.add(perm);
7919            }
7920        }
7921
7922        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7923        if (trimCount <= 0) return false;
7924
7925        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7926        for (int i = 0; i < trimCount; i++) {
7927            final UriPermission perm = persisted.get(i);
7928
7929            if (DEBUG_URI_PERMISSION) {
7930                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7931            }
7932
7933            perm.releasePersistableModes(~0);
7934            removeUriPermissionIfNeededLocked(perm);
7935        }
7936
7937        return true;
7938    }
7939
7940    @Override
7941    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7942            String packageName, boolean incoming) {
7943        enforceNotIsolatedCaller("getPersistedUriPermissions");
7944        Preconditions.checkNotNull(packageName, "packageName");
7945
7946        final int callingUid = Binder.getCallingUid();
7947        final IPackageManager pm = AppGlobals.getPackageManager();
7948        try {
7949            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7950            if (packageUid != callingUid) {
7951                throw new SecurityException(
7952                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7953            }
7954        } catch (RemoteException e) {
7955            throw new SecurityException("Failed to verify package name ownership");
7956        }
7957
7958        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7959        synchronized (this) {
7960            if (incoming) {
7961                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7962                        callingUid);
7963                if (perms == null) {
7964                    Slog.w(TAG, "No permission grants found for " + packageName);
7965                } else {
7966                    for (UriPermission perm : perms.values()) {
7967                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7968                            result.add(perm.buildPersistedPublicApiObject());
7969                        }
7970                    }
7971                }
7972            } else {
7973                final int size = mGrantedUriPermissions.size();
7974                for (int i = 0; i < size; i++) {
7975                    final ArrayMap<GrantUri, UriPermission> perms =
7976                            mGrantedUriPermissions.valueAt(i);
7977                    for (UriPermission perm : perms.values()) {
7978                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7979                            result.add(perm.buildPersistedPublicApiObject());
7980                        }
7981                    }
7982                }
7983            }
7984        }
7985        return new ParceledListSlice<android.content.UriPermission>(result);
7986    }
7987
7988    @Override
7989    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7990        synchronized (this) {
7991            ProcessRecord app =
7992                who != null ? getRecordForAppLocked(who) : null;
7993            if (app == null) return;
7994
7995            Message msg = Message.obtain();
7996            msg.what = WAIT_FOR_DEBUGGER_MSG;
7997            msg.obj = app;
7998            msg.arg1 = waiting ? 1 : 0;
7999            mHandler.sendMessage(msg);
8000        }
8001    }
8002
8003    @Override
8004    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8005        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8006        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8007        outInfo.availMem = Process.getFreeMemory();
8008        outInfo.totalMem = Process.getTotalMemory();
8009        outInfo.threshold = homeAppMem;
8010        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8011        outInfo.hiddenAppThreshold = cachedAppMem;
8012        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8013                ProcessList.SERVICE_ADJ);
8014        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8015                ProcessList.VISIBLE_APP_ADJ);
8016        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8017                ProcessList.FOREGROUND_APP_ADJ);
8018    }
8019
8020    // =========================================================
8021    // TASK MANAGEMENT
8022    // =========================================================
8023
8024    @Override
8025    public List<IAppTask> getAppTasks(String callingPackage) {
8026        int callingUid = Binder.getCallingUid();
8027        long ident = Binder.clearCallingIdentity();
8028
8029        synchronized(this) {
8030            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8031            try {
8032                if (localLOGV) Slog.v(TAG, "getAppTasks");
8033
8034                final int N = mRecentTasks.size();
8035                for (int i = 0; i < N; i++) {
8036                    TaskRecord tr = mRecentTasks.get(i);
8037                    // Skip tasks that do not match the caller.  We don't need to verify
8038                    // callingPackage, because we are also limiting to callingUid and know
8039                    // that will limit to the correct security sandbox.
8040                    if (tr.effectiveUid != callingUid) {
8041                        continue;
8042                    }
8043                    Intent intent = tr.getBaseIntent();
8044                    if (intent == null ||
8045                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8046                        continue;
8047                    }
8048                    ActivityManager.RecentTaskInfo taskInfo =
8049                            createRecentTaskInfoFromTaskRecord(tr);
8050                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8051                    list.add(taskImpl);
8052                }
8053            } finally {
8054                Binder.restoreCallingIdentity(ident);
8055            }
8056            return list;
8057        }
8058    }
8059
8060    @Override
8061    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8062        final int callingUid = Binder.getCallingUid();
8063        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8064
8065        synchronized(this) {
8066            if (localLOGV) Slog.v(
8067                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8068
8069            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8070                    callingUid);
8071
8072            // TODO: Improve with MRU list from all ActivityStacks.
8073            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8074        }
8075
8076        return list;
8077    }
8078
8079    /**
8080     * Creates a new RecentTaskInfo from a TaskRecord.
8081     */
8082    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8083        // Update the task description to reflect any changes in the task stack
8084        tr.updateTaskDescription();
8085
8086        // Compose the recent task info
8087        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8088        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8089        rti.persistentId = tr.taskId;
8090        rti.baseIntent = new Intent(tr.getBaseIntent());
8091        rti.origActivity = tr.origActivity;
8092        rti.description = tr.lastDescription;
8093        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8094        rti.userId = tr.userId;
8095        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8096        rti.firstActiveTime = tr.firstActiveTime;
8097        rti.lastActiveTime = tr.lastActiveTime;
8098        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8099        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8100        return rti;
8101    }
8102
8103    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8104        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8105                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8106        if (!allowed) {
8107            if (checkPermission(android.Manifest.permission.GET_TASKS,
8108                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8109                // Temporary compatibility: some existing apps on the system image may
8110                // still be requesting the old permission and not switched to the new
8111                // one; if so, we'll still allow them full access.  This means we need
8112                // to see if they are holding the old permission and are a system app.
8113                try {
8114                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8115                        allowed = true;
8116                        Slog.w(TAG, caller + ": caller " + callingUid
8117                                + " is using old GET_TASKS but privileged; allowing");
8118                    }
8119                } catch (RemoteException e) {
8120                }
8121            }
8122        }
8123        if (!allowed) {
8124            Slog.w(TAG, caller + ": caller " + callingUid
8125                    + " does not hold GET_TASKS; limiting output");
8126        }
8127        return allowed;
8128    }
8129
8130    @Override
8131    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8132        final int callingUid = Binder.getCallingUid();
8133        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8134                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8135
8136        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8137        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8138        synchronized (this) {
8139            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8140                    callingUid);
8141            final boolean detailed = checkCallingPermission(
8142                    android.Manifest.permission.GET_DETAILED_TASKS)
8143                    == PackageManager.PERMISSION_GRANTED;
8144
8145            final int N = mRecentTasks.size();
8146            ArrayList<ActivityManager.RecentTaskInfo> res
8147                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8148                            maxNum < N ? maxNum : N);
8149
8150            final Set<Integer> includedUsers;
8151            if (includeProfiles) {
8152                includedUsers = getProfileIdsLocked(userId);
8153            } else {
8154                includedUsers = new HashSet<Integer>();
8155            }
8156            includedUsers.add(Integer.valueOf(userId));
8157
8158            for (int i=0; i<N && maxNum > 0; i++) {
8159                TaskRecord tr = mRecentTasks.get(i);
8160                // Only add calling user or related users recent tasks
8161                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8162                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8163                    continue;
8164                }
8165
8166                // Return the entry if desired by the caller.  We always return
8167                // the first entry, because callers always expect this to be the
8168                // foreground app.  We may filter others if the caller has
8169                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8170                // we should exclude the entry.
8171
8172                if (i == 0
8173                        || withExcluded
8174                        || (tr.intent == null)
8175                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8176                                == 0)) {
8177                    if (!allowed) {
8178                        // If the caller doesn't have the GET_TASKS permission, then only
8179                        // allow them to see a small subset of tasks -- their own and home.
8180                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8181                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8182                            continue;
8183                        }
8184                    }
8185                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8186                        if (tr.stack != null && tr.stack.isHomeStack()) {
8187                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8188                            continue;
8189                        }
8190                    }
8191                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8192                        // Don't include auto remove tasks that are finished or finishing.
8193                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8194                                + tr);
8195                        continue;
8196                    }
8197                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8198                            && !tr.isAvailable) {
8199                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8200                        continue;
8201                    }
8202
8203                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8204                    if (!detailed) {
8205                        rti.baseIntent.replaceExtras((Bundle)null);
8206                    }
8207
8208                    res.add(rti);
8209                    maxNum--;
8210                }
8211            }
8212            return res;
8213        }
8214    }
8215
8216    TaskRecord recentTaskForIdLocked(int id) {
8217        final int N = mRecentTasks.size();
8218            for (int i=0; i<N; i++) {
8219                TaskRecord tr = mRecentTasks.get(i);
8220                if (tr.taskId == id) {
8221                    return tr;
8222                }
8223            }
8224            return null;
8225    }
8226
8227    @Override
8228    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8229        synchronized (this) {
8230            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8231                    "getTaskThumbnail()");
8232            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
8233            if (tr != null) {
8234                return tr.getTaskThumbnailLocked();
8235            }
8236        }
8237        return null;
8238    }
8239
8240    @Override
8241    public int addAppTask(IBinder activityToken, Intent intent,
8242            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8243        final int callingUid = Binder.getCallingUid();
8244        final long callingIdent = Binder.clearCallingIdentity();
8245
8246        try {
8247            synchronized (this) {
8248                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8249                if (r == null) {
8250                    throw new IllegalArgumentException("Activity does not exist; token="
8251                            + activityToken);
8252                }
8253                ComponentName comp = intent.getComponent();
8254                if (comp == null) {
8255                    throw new IllegalArgumentException("Intent " + intent
8256                            + " must specify explicit component");
8257                }
8258                if (thumbnail.getWidth() != mThumbnailWidth
8259                        || thumbnail.getHeight() != mThumbnailHeight) {
8260                    throw new IllegalArgumentException("Bad thumbnail size: got "
8261                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8262                            + mThumbnailWidth + "x" + mThumbnailHeight);
8263                }
8264                if (intent.getSelector() != null) {
8265                    intent.setSelector(null);
8266                }
8267                if (intent.getSourceBounds() != null) {
8268                    intent.setSourceBounds(null);
8269                }
8270                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8271                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8272                        // The caller has added this as an auto-remove task...  that makes no
8273                        // sense, so turn off auto-remove.
8274                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8275                    }
8276                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8277                    // Must be a new task.
8278                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8279                }
8280                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8281                    mLastAddedTaskActivity = null;
8282                }
8283                ActivityInfo ainfo = mLastAddedTaskActivity;
8284                if (ainfo == null) {
8285                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8286                            comp, 0, UserHandle.getUserId(callingUid));
8287                    if (ainfo.applicationInfo.uid != callingUid) {
8288                        throw new SecurityException(
8289                                "Can't add task for another application: target uid="
8290                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8291                    }
8292                }
8293
8294                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8295                        intent, description);
8296
8297                int trimIdx = trimRecentsForTaskLocked(task, false);
8298                if (trimIdx >= 0) {
8299                    // If this would have caused a trim, then we'll abort because that
8300                    // means it would be added at the end of the list but then just removed.
8301                    return INVALID_TASK_ID;
8302                }
8303
8304                final int N = mRecentTasks.size();
8305                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8306                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8307                    tr.removedFromRecents();
8308                }
8309
8310                task.inRecents = true;
8311                mRecentTasks.add(task);
8312                r.task.stack.addTask(task, false, false);
8313
8314                task.setLastThumbnail(thumbnail);
8315                task.freeLastThumbnail();
8316
8317                return task.taskId;
8318            }
8319        } finally {
8320            Binder.restoreCallingIdentity(callingIdent);
8321        }
8322    }
8323
8324    @Override
8325    public Point getAppTaskThumbnailSize() {
8326        synchronized (this) {
8327            return new Point(mThumbnailWidth,  mThumbnailHeight);
8328        }
8329    }
8330
8331    @Override
8332    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8333        synchronized (this) {
8334            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8335            if (r != null) {
8336                r.setTaskDescription(td);
8337                r.task.updateTaskDescription();
8338            }
8339        }
8340    }
8341
8342    @Override
8343    public Bitmap getTaskDescriptionIcon(String filename) {
8344        if (!FileUtils.isValidExtFilename(filename)
8345                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8346            throw new IllegalArgumentException("Bad filename: " + filename);
8347        }
8348        return mTaskPersister.getTaskDescriptionIcon(filename);
8349    }
8350
8351    @Override
8352    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8353            throws RemoteException {
8354        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8355                opts.getCustomInPlaceResId() == 0) {
8356            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8357                    "with valid animation");
8358        }
8359        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8360        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8361                opts.getCustomInPlaceResId());
8362        mWindowManager.executeAppTransition();
8363    }
8364
8365    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8366        mRecentTasks.remove(tr);
8367        tr.removedFromRecents();
8368        ComponentName component = tr.getBaseIntent().getComponent();
8369        if (component == null) {
8370            Slog.w(TAG, "No component for base intent of task: " + tr);
8371            return;
8372        }
8373
8374        if (!killProcess) {
8375            return;
8376        }
8377
8378        // Determine if the process(es) for this task should be killed.
8379        final String pkg = component.getPackageName();
8380        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8381        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8382        for (int i = 0; i < pmap.size(); i++) {
8383
8384            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8385            for (int j = 0; j < uids.size(); j++) {
8386                ProcessRecord proc = uids.valueAt(j);
8387                if (proc.userId != tr.userId) {
8388                    // Don't kill process for a different user.
8389                    continue;
8390                }
8391                if (proc == mHomeProcess) {
8392                    // Don't kill the home process along with tasks from the same package.
8393                    continue;
8394                }
8395                if (!proc.pkgList.containsKey(pkg)) {
8396                    // Don't kill process that is not associated with this task.
8397                    continue;
8398                }
8399
8400                for (int k = 0; k < proc.activities.size(); k++) {
8401                    TaskRecord otherTask = proc.activities.get(k).task;
8402                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8403                        // Don't kill process(es) that has an activity in a different task that is
8404                        // also in recents.
8405                        return;
8406                    }
8407                }
8408
8409                // Add process to kill list.
8410                procsToKill.add(proc);
8411            }
8412        }
8413
8414        // Find any running services associated with this app and stop if needed.
8415        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8416
8417        // Kill the running processes.
8418        for (int i = 0; i < procsToKill.size(); i++) {
8419            ProcessRecord pr = procsToKill.get(i);
8420            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8421                pr.kill("remove task", true);
8422            } else {
8423                pr.waitingToKill = "remove task";
8424            }
8425        }
8426    }
8427
8428    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8429        // Remove all tasks with activities in the specified package from the list of recent tasks
8430        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8431            TaskRecord tr = mRecentTasks.get(i);
8432            if (tr.userId != userId) continue;
8433
8434            ComponentName cn = tr.intent.getComponent();
8435            if (cn != null && cn.getPackageName().equals(packageName)) {
8436                // If the package name matches, remove the task.
8437                removeTaskByIdLocked(tr.taskId, true);
8438            }
8439        }
8440    }
8441
8442    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8443        final IPackageManager pm = AppGlobals.getPackageManager();
8444        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8445
8446        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8447            TaskRecord tr = mRecentTasks.get(i);
8448            if (tr.userId != userId) continue;
8449
8450            ComponentName cn = tr.intent.getComponent();
8451            if (cn != null && cn.getPackageName().equals(packageName)) {
8452                // Skip if component still exists in the package.
8453                if (componentsKnownToExist.contains(cn)) continue;
8454
8455                try {
8456                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8457                    if (info != null) {
8458                        componentsKnownToExist.add(cn);
8459                    } else {
8460                        removeTaskByIdLocked(tr.taskId, false);
8461                    }
8462                } catch (RemoteException e) {
8463                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8464                }
8465            }
8466        }
8467    }
8468
8469    /**
8470     * Removes the task with the specified task id.
8471     *
8472     * @param taskId Identifier of the task to be removed.
8473     * @param killProcess Kill any process associated with the task if possible.
8474     * @return Returns true if the given task was found and removed.
8475     */
8476    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8477        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8478        if (tr != null) {
8479            tr.removeTaskActivitiesLocked();
8480            cleanUpRemovedTaskLocked(tr, killProcess);
8481            if (tr.isPersistable) {
8482                notifyTaskPersisterLocked(null, true);
8483            }
8484            return true;
8485        }
8486        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8487        return false;
8488    }
8489
8490    @Override
8491    public boolean removeTask(int taskId) {
8492        synchronized (this) {
8493            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8494                    "removeTask()");
8495            long ident = Binder.clearCallingIdentity();
8496            try {
8497                return removeTaskByIdLocked(taskId, true);
8498            } finally {
8499                Binder.restoreCallingIdentity(ident);
8500            }
8501        }
8502    }
8503
8504    /**
8505     * TODO: Add mController hook
8506     */
8507    @Override
8508    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8509        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8510                "moveTaskToFront()");
8511
8512        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8513        synchronized(this) {
8514            moveTaskToFrontLocked(taskId, flags, options);
8515        }
8516    }
8517
8518    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8519        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8520                Binder.getCallingUid(), -1, -1, "Task to front")) {
8521            ActivityOptions.abort(options);
8522            return;
8523        }
8524        final long origId = Binder.clearCallingIdentity();
8525        try {
8526            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8527            if (task == null) {
8528                Slog.d(TAG, "Could not find task for id: "+ taskId);
8529                return;
8530            }
8531            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8532                mStackSupervisor.showLockTaskToast();
8533                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8534                return;
8535            }
8536            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8537            if (prev != null && prev.isRecentsActivity()) {
8538                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8539            }
8540            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8541        } finally {
8542            Binder.restoreCallingIdentity(origId);
8543        }
8544        ActivityOptions.abort(options);
8545    }
8546
8547    @Override
8548    public void moveTaskToBack(int taskId) {
8549        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8550                "moveTaskToBack()");
8551
8552        synchronized(this) {
8553            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8554            if (tr != null) {
8555                if (tr == mStackSupervisor.mLockTaskModeTask) {
8556                    mStackSupervisor.showLockTaskToast();
8557                    return;
8558                }
8559                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8560                ActivityStack stack = tr.stack;
8561                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8562                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8563                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8564                        return;
8565                    }
8566                }
8567                final long origId = Binder.clearCallingIdentity();
8568                try {
8569                    stack.moveTaskToBackLocked(taskId);
8570                } finally {
8571                    Binder.restoreCallingIdentity(origId);
8572                }
8573            }
8574        }
8575    }
8576
8577    /**
8578     * Moves an activity, and all of the other activities within the same task, to the bottom
8579     * of the history stack.  The activity's order within the task is unchanged.
8580     *
8581     * @param token A reference to the activity we wish to move
8582     * @param nonRoot If false then this only works if the activity is the root
8583     *                of a task; if true it will work for any activity in a task.
8584     * @return Returns true if the move completed, false if not.
8585     */
8586    @Override
8587    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8588        enforceNotIsolatedCaller("moveActivityTaskToBack");
8589        synchronized(this) {
8590            final long origId = Binder.clearCallingIdentity();
8591            try {
8592                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8593                if (taskId >= 0) {
8594                    if ((mStackSupervisor.mLockTaskModeTask != null)
8595                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8596                        mStackSupervisor.showLockTaskToast();
8597                        return false;
8598                    }
8599                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8600                }
8601            } finally {
8602                Binder.restoreCallingIdentity(origId);
8603            }
8604        }
8605        return false;
8606    }
8607
8608    @Override
8609    public void moveTaskBackwards(int task) {
8610        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8611                "moveTaskBackwards()");
8612
8613        synchronized(this) {
8614            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8615                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8616                return;
8617            }
8618            final long origId = Binder.clearCallingIdentity();
8619            moveTaskBackwardsLocked(task);
8620            Binder.restoreCallingIdentity(origId);
8621        }
8622    }
8623
8624    private final void moveTaskBackwardsLocked(int task) {
8625        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8626    }
8627
8628    @Override
8629    public IBinder getHomeActivityToken() throws RemoteException {
8630        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8631                "getHomeActivityToken()");
8632        synchronized (this) {
8633            return mStackSupervisor.getHomeActivityToken();
8634        }
8635    }
8636
8637    @Override
8638    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8639            IActivityContainerCallback callback) throws RemoteException {
8640        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8641                "createActivityContainer()");
8642        synchronized (this) {
8643            if (parentActivityToken == null) {
8644                throw new IllegalArgumentException("parent token must not be null");
8645            }
8646            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8647            if (r == null) {
8648                return null;
8649            }
8650            if (callback == null) {
8651                throw new IllegalArgumentException("callback must not be null");
8652            }
8653            return mStackSupervisor.createActivityContainer(r, callback);
8654        }
8655    }
8656
8657    @Override
8658    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8659        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8660                "deleteActivityContainer()");
8661        synchronized (this) {
8662            mStackSupervisor.deleteActivityContainer(container);
8663        }
8664    }
8665
8666    @Override
8667    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8668        synchronized (this) {
8669            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8670            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8671                return stack.mActivityContainer.getDisplayId();
8672            }
8673            return Display.DEFAULT_DISPLAY;
8674        }
8675    }
8676
8677    @Override
8678    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8679        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8680                "moveTaskToStack()");
8681        if (stackId == HOME_STACK_ID) {
8682            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8683                    new RuntimeException("here").fillInStackTrace());
8684        }
8685        synchronized (this) {
8686            long ident = Binder.clearCallingIdentity();
8687            try {
8688                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8689                        + stackId + " toTop=" + toTop);
8690                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8691            } finally {
8692                Binder.restoreCallingIdentity(ident);
8693            }
8694        }
8695    }
8696
8697    @Override
8698    public void resizeStack(int stackBoxId, Rect bounds) {
8699        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8700                "resizeStackBox()");
8701        long ident = Binder.clearCallingIdentity();
8702        try {
8703            mWindowManager.resizeStack(stackBoxId, bounds);
8704        } finally {
8705            Binder.restoreCallingIdentity(ident);
8706        }
8707    }
8708
8709    @Override
8710    public List<StackInfo> getAllStackInfos() {
8711        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8712                "getAllStackInfos()");
8713        long ident = Binder.clearCallingIdentity();
8714        try {
8715            synchronized (this) {
8716                return mStackSupervisor.getAllStackInfosLocked();
8717            }
8718        } finally {
8719            Binder.restoreCallingIdentity(ident);
8720        }
8721    }
8722
8723    @Override
8724    public StackInfo getStackInfo(int stackId) {
8725        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8726                "getStackInfo()");
8727        long ident = Binder.clearCallingIdentity();
8728        try {
8729            synchronized (this) {
8730                return mStackSupervisor.getStackInfoLocked(stackId);
8731            }
8732        } finally {
8733            Binder.restoreCallingIdentity(ident);
8734        }
8735    }
8736
8737    @Override
8738    public boolean isInHomeStack(int taskId) {
8739        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8740                "getStackInfo()");
8741        long ident = Binder.clearCallingIdentity();
8742        try {
8743            synchronized (this) {
8744                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8745                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8746            }
8747        } finally {
8748            Binder.restoreCallingIdentity(ident);
8749        }
8750    }
8751
8752    @Override
8753    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8754        synchronized(this) {
8755            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8756        }
8757    }
8758
8759    private boolean isLockTaskAuthorized(String pkg) {
8760        final DevicePolicyManager dpm = (DevicePolicyManager)
8761                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8762        try {
8763            int uid = mContext.getPackageManager().getPackageUid(pkg,
8764                    Binder.getCallingUserHandle().getIdentifier());
8765            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8766        } catch (NameNotFoundException e) {
8767            return false;
8768        }
8769    }
8770
8771    void startLockTaskMode(TaskRecord task) {
8772        final String pkg;
8773        synchronized (this) {
8774            pkg = task.intent.getComponent().getPackageName();
8775        }
8776        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8777        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8778            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8779                    StatusBarManagerInternal.class);
8780            if (statusBarManager != null) {
8781                statusBarManager.showScreenPinningRequest();
8782            }
8783            return;
8784        }
8785        long ident = Binder.clearCallingIdentity();
8786        try {
8787            synchronized (this) {
8788                // Since we lost lock on task, make sure it is still there.
8789                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8790                if (task != null) {
8791                    if (!isSystemInitiated
8792                            && ((mStackSupervisor.getFocusedStack() == null)
8793                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8794                        throw new IllegalArgumentException("Invalid task, not in foreground");
8795                    }
8796                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated,
8797                            "startLockTask");
8798                }
8799            }
8800        } finally {
8801            Binder.restoreCallingIdentity(ident);
8802        }
8803    }
8804
8805    @Override
8806    public void startLockTaskMode(int taskId) {
8807        final TaskRecord task;
8808        long ident = Binder.clearCallingIdentity();
8809        try {
8810            synchronized (this) {
8811                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8812            }
8813        } finally {
8814            Binder.restoreCallingIdentity(ident);
8815        }
8816        if (task != null) {
8817            startLockTaskMode(task);
8818        }
8819    }
8820
8821    @Override
8822    public void startLockTaskMode(IBinder token) {
8823        final TaskRecord task;
8824        long ident = Binder.clearCallingIdentity();
8825        try {
8826            synchronized (this) {
8827                final ActivityRecord r = ActivityRecord.forToken(token);
8828                if (r == null) {
8829                    return;
8830                }
8831                task = r.task;
8832            }
8833        } finally {
8834            Binder.restoreCallingIdentity(ident);
8835        }
8836        if (task != null) {
8837            startLockTaskMode(task);
8838        }
8839    }
8840
8841    @Override
8842    public void startLockTaskModeOnCurrent() throws RemoteException {
8843        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8844                "startLockTaskModeOnCurrent");
8845        long ident = Binder.clearCallingIdentity();
8846        try {
8847            ActivityRecord r = null;
8848            synchronized (this) {
8849                r = mStackSupervisor.topRunningActivityLocked();
8850            }
8851            startLockTaskMode(r.task);
8852        } finally {
8853            Binder.restoreCallingIdentity(ident);
8854        }
8855    }
8856
8857    @Override
8858    public void stopLockTaskMode() {
8859        // Verify that the user matches the package of the intent for the TaskRecord
8860        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8861        // and stopLockTaskMode.
8862        final int callingUid = Binder.getCallingUid();
8863        if (callingUid != Process.SYSTEM_UID) {
8864            try {
8865                String pkg =
8866                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8867                int uid = mContext.getPackageManager().getPackageUid(pkg,
8868                        Binder.getCallingUserHandle().getIdentifier());
8869                if (uid != callingUid) {
8870                    throw new SecurityException("Invalid uid, expected " + uid);
8871                }
8872            } catch (NameNotFoundException e) {
8873                Log.d(TAG, "stopLockTaskMode " + e);
8874                return;
8875            }
8876        }
8877        long ident = Binder.clearCallingIdentity();
8878        try {
8879            Log.d(TAG, "stopLockTaskMode");
8880            // Stop lock task
8881            synchronized (this) {
8882                mStackSupervisor.setLockTaskModeLocked(null, false, "stopLockTask");
8883            }
8884        } finally {
8885            Binder.restoreCallingIdentity(ident);
8886        }
8887    }
8888
8889    @Override
8890    public void stopLockTaskModeOnCurrent() throws RemoteException {
8891        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8892                "stopLockTaskModeOnCurrent");
8893        long ident = Binder.clearCallingIdentity();
8894        try {
8895            stopLockTaskMode();
8896        } finally {
8897            Binder.restoreCallingIdentity(ident);
8898        }
8899    }
8900
8901    @Override
8902    public boolean isInLockTaskMode() {
8903        synchronized (this) {
8904            return mStackSupervisor.isInLockTaskMode();
8905        }
8906    }
8907
8908    // =========================================================
8909    // CONTENT PROVIDERS
8910    // =========================================================
8911
8912    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8913        List<ProviderInfo> providers = null;
8914        try {
8915            providers = AppGlobals.getPackageManager().
8916                queryContentProviders(app.processName, app.uid,
8917                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8918        } catch (RemoteException ex) {
8919        }
8920        if (DEBUG_MU)
8921            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8922        int userId = app.userId;
8923        if (providers != null) {
8924            int N = providers.size();
8925            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8926            for (int i=0; i<N; i++) {
8927                ProviderInfo cpi =
8928                    (ProviderInfo)providers.get(i);
8929                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8930                        cpi.name, cpi.flags);
8931                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8932                    // This is a singleton provider, but a user besides the
8933                    // default user is asking to initialize a process it runs
8934                    // in...  well, no, it doesn't actually run in this process,
8935                    // it runs in the process of the default user.  Get rid of it.
8936                    providers.remove(i);
8937                    N--;
8938                    i--;
8939                    continue;
8940                }
8941
8942                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8943                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8944                if (cpr == null) {
8945                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8946                    mProviderMap.putProviderByClass(comp, cpr);
8947                }
8948                if (DEBUG_MU)
8949                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8950                app.pubProviders.put(cpi.name, cpr);
8951                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8952                    // Don't add this if it is a platform component that is marked
8953                    // to run in multiple processes, because this is actually
8954                    // part of the framework so doesn't make sense to track as a
8955                    // separate apk in the process.
8956                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8957                            mProcessStats);
8958                }
8959                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8960            }
8961        }
8962        return providers;
8963    }
8964
8965    /**
8966     * Check if {@link ProcessRecord} has a possible chance at accessing the
8967     * given {@link ProviderInfo}. Final permission checking is always done
8968     * in {@link ContentProvider}.
8969     */
8970    private final String checkContentProviderPermissionLocked(
8971            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8972        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8973        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8974        boolean checkedGrants = false;
8975        if (checkUser) {
8976            // Looking for cross-user grants before enforcing the typical cross-users permissions
8977            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8978            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8979                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8980                    return null;
8981                }
8982                checkedGrants = true;
8983            }
8984            userId = handleIncomingUser(callingPid, callingUid, userId,
8985                    false, ALLOW_NON_FULL,
8986                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8987            if (userId != tmpTargetUserId) {
8988                // When we actually went to determine the final targer user ID, this ended
8989                // up different than our initial check for the authority.  This is because
8990                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8991                // SELF.  So we need to re-check the grants again.
8992                checkedGrants = false;
8993            }
8994        }
8995        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8996                cpi.applicationInfo.uid, cpi.exported)
8997                == PackageManager.PERMISSION_GRANTED) {
8998            return null;
8999        }
9000        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9001                cpi.applicationInfo.uid, cpi.exported)
9002                == PackageManager.PERMISSION_GRANTED) {
9003            return null;
9004        }
9005
9006        PathPermission[] pps = cpi.pathPermissions;
9007        if (pps != null) {
9008            int i = pps.length;
9009            while (i > 0) {
9010                i--;
9011                PathPermission pp = pps[i];
9012                String pprperm = pp.getReadPermission();
9013                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9014                        cpi.applicationInfo.uid, cpi.exported)
9015                        == PackageManager.PERMISSION_GRANTED) {
9016                    return null;
9017                }
9018                String ppwperm = pp.getWritePermission();
9019                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9020                        cpi.applicationInfo.uid, cpi.exported)
9021                        == PackageManager.PERMISSION_GRANTED) {
9022                    return null;
9023                }
9024            }
9025        }
9026        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9027            return null;
9028        }
9029
9030        String msg;
9031        if (!cpi.exported) {
9032            msg = "Permission Denial: opening provider " + cpi.name
9033                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9034                    + ", uid=" + callingUid + ") that is not exported from uid "
9035                    + cpi.applicationInfo.uid;
9036        } else {
9037            msg = "Permission Denial: opening provider " + cpi.name
9038                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9039                    + ", uid=" + callingUid + ") requires "
9040                    + cpi.readPermission + " or " + cpi.writePermission;
9041        }
9042        Slog.w(TAG, msg);
9043        return msg;
9044    }
9045
9046    /**
9047     * Returns if the ContentProvider has granted a uri to callingUid
9048     */
9049    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9050        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9051        if (perms != null) {
9052            for (int i=perms.size()-1; i>=0; i--) {
9053                GrantUri grantUri = perms.keyAt(i);
9054                if (grantUri.sourceUserId == userId || !checkUser) {
9055                    if (matchesProvider(grantUri.uri, cpi)) {
9056                        return true;
9057                    }
9058                }
9059            }
9060        }
9061        return false;
9062    }
9063
9064    /**
9065     * Returns true if the uri authority is one of the authorities specified in the provider.
9066     */
9067    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9068        String uriAuth = uri.getAuthority();
9069        String cpiAuth = cpi.authority;
9070        if (cpiAuth.indexOf(';') == -1) {
9071            return cpiAuth.equals(uriAuth);
9072        }
9073        String[] cpiAuths = cpiAuth.split(";");
9074        int length = cpiAuths.length;
9075        for (int i = 0; i < length; i++) {
9076            if (cpiAuths[i].equals(uriAuth)) return true;
9077        }
9078        return false;
9079    }
9080
9081    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9082            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9083        if (r != null) {
9084            for (int i=0; i<r.conProviders.size(); i++) {
9085                ContentProviderConnection conn = r.conProviders.get(i);
9086                if (conn.provider == cpr) {
9087                    if (DEBUG_PROVIDER) Slog.v(TAG,
9088                            "Adding provider requested by "
9089                            + r.processName + " from process "
9090                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9091                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9092                    if (stable) {
9093                        conn.stableCount++;
9094                        conn.numStableIncs++;
9095                    } else {
9096                        conn.unstableCount++;
9097                        conn.numUnstableIncs++;
9098                    }
9099                    return conn;
9100                }
9101            }
9102            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9103            if (stable) {
9104                conn.stableCount = 1;
9105                conn.numStableIncs = 1;
9106            } else {
9107                conn.unstableCount = 1;
9108                conn.numUnstableIncs = 1;
9109            }
9110            cpr.connections.add(conn);
9111            r.conProviders.add(conn);
9112            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9113            return conn;
9114        }
9115        cpr.addExternalProcessHandleLocked(externalProcessToken);
9116        return null;
9117    }
9118
9119    boolean decProviderCountLocked(ContentProviderConnection conn,
9120            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9121        if (conn != null) {
9122            cpr = conn.provider;
9123            if (DEBUG_PROVIDER) Slog.v(TAG,
9124                    "Removing provider requested by "
9125                    + conn.client.processName + " from process "
9126                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9127                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9128            if (stable) {
9129                conn.stableCount--;
9130            } else {
9131                conn.unstableCount--;
9132            }
9133            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9134                cpr.connections.remove(conn);
9135                conn.client.conProviders.remove(conn);
9136                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9137                return true;
9138            }
9139            return false;
9140        }
9141        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9142        return false;
9143    }
9144
9145    private void checkTime(long startTime, String where) {
9146        long now = SystemClock.elapsedRealtime();
9147        if ((now-startTime) > 1000) {
9148            // If we are taking more than a second, log about it.
9149            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9150        }
9151    }
9152
9153    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9154            String name, IBinder token, boolean stable, int userId) {
9155        ContentProviderRecord cpr;
9156        ContentProviderConnection conn = null;
9157        ProviderInfo cpi = null;
9158
9159        synchronized(this) {
9160            long startTime = SystemClock.elapsedRealtime();
9161
9162            ProcessRecord r = null;
9163            if (caller != null) {
9164                r = getRecordForAppLocked(caller);
9165                if (r == null) {
9166                    throw new SecurityException(
9167                            "Unable to find app for caller " + caller
9168                          + " (pid=" + Binder.getCallingPid()
9169                          + ") when getting content provider " + name);
9170                }
9171            }
9172
9173            boolean checkCrossUser = true;
9174
9175            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9176
9177            // First check if this content provider has been published...
9178            cpr = mProviderMap.getProviderByName(name, userId);
9179            // If that didn't work, check if it exists for user 0 and then
9180            // verify that it's a singleton provider before using it.
9181            if (cpr == null && userId != UserHandle.USER_OWNER) {
9182                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9183                if (cpr != null) {
9184                    cpi = cpr.info;
9185                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9186                            cpi.name, cpi.flags)
9187                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9188                        userId = UserHandle.USER_OWNER;
9189                        checkCrossUser = false;
9190                    } else {
9191                        cpr = null;
9192                        cpi = null;
9193                    }
9194                }
9195            }
9196
9197            boolean providerRunning = cpr != null;
9198            if (providerRunning) {
9199                cpi = cpr.info;
9200                String msg;
9201                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9202                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9203                        != null) {
9204                    throw new SecurityException(msg);
9205                }
9206                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9207
9208                if (r != null && cpr.canRunHere(r)) {
9209                    // This provider has been published or is in the process
9210                    // of being published...  but it is also allowed to run
9211                    // in the caller's process, so don't make a connection
9212                    // and just let the caller instantiate its own instance.
9213                    ContentProviderHolder holder = cpr.newHolder(null);
9214                    // don't give caller the provider object, it needs
9215                    // to make its own.
9216                    holder.provider = null;
9217                    return holder;
9218                }
9219
9220                final long origId = Binder.clearCallingIdentity();
9221
9222                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9223
9224                // In this case the provider instance already exists, so we can
9225                // return it right away.
9226                conn = incProviderCountLocked(r, cpr, token, stable);
9227                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9228                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9229                        // If this is a perceptible app accessing the provider,
9230                        // make sure to count it as being accessed and thus
9231                        // back up on the LRU list.  This is good because
9232                        // content providers are often expensive to start.
9233                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9234                        updateLruProcessLocked(cpr.proc, false, null);
9235                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9236                    }
9237                }
9238
9239                if (cpr.proc != null) {
9240                    if (false) {
9241                        if (cpr.name.flattenToShortString().equals(
9242                                "com.android.providers.calendar/.CalendarProvider2")) {
9243                            Slog.v(TAG, "****************** KILLING "
9244                                + cpr.name.flattenToShortString());
9245                            Process.killProcess(cpr.proc.pid);
9246                        }
9247                    }
9248                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9249                    boolean success = updateOomAdjLocked(cpr.proc);
9250                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9251                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9252                    // NOTE: there is still a race here where a signal could be
9253                    // pending on the process even though we managed to update its
9254                    // adj level.  Not sure what to do about this, but at least
9255                    // the race is now smaller.
9256                    if (!success) {
9257                        // Uh oh...  it looks like the provider's process
9258                        // has been killed on us.  We need to wait for a new
9259                        // process to be started, and make sure its death
9260                        // doesn't kill our process.
9261                        Slog.i(TAG,
9262                                "Existing provider " + cpr.name.flattenToShortString()
9263                                + " is crashing; detaching " + r);
9264                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9265                        checkTime(startTime, "getContentProviderImpl: before appDied");
9266                        appDiedLocked(cpr.proc);
9267                        checkTime(startTime, "getContentProviderImpl: after appDied");
9268                        if (!lastRef) {
9269                            // This wasn't the last ref our process had on
9270                            // the provider...  we have now been killed, bail.
9271                            return null;
9272                        }
9273                        providerRunning = false;
9274                        conn = null;
9275                    }
9276                }
9277
9278                Binder.restoreCallingIdentity(origId);
9279            }
9280
9281            boolean singleton;
9282            if (!providerRunning) {
9283                try {
9284                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9285                    cpi = AppGlobals.getPackageManager().
9286                        resolveContentProvider(name,
9287                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9288                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9289                } catch (RemoteException ex) {
9290                }
9291                if (cpi == null) {
9292                    return null;
9293                }
9294                // If the provider is a singleton AND
9295                // (it's a call within the same user || the provider is a
9296                // privileged app)
9297                // Then allow connecting to the singleton provider
9298                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9299                        cpi.name, cpi.flags)
9300                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9301                if (singleton) {
9302                    userId = UserHandle.USER_OWNER;
9303                }
9304                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9305                checkTime(startTime, "getContentProviderImpl: got app info for user");
9306
9307                String msg;
9308                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9309                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9310                        != null) {
9311                    throw new SecurityException(msg);
9312                }
9313                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9314
9315                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9316                        && !cpi.processName.equals("system")) {
9317                    // If this content provider does not run in the system
9318                    // process, and the system is not yet ready to run other
9319                    // processes, then fail fast instead of hanging.
9320                    throw new IllegalArgumentException(
9321                            "Attempt to launch content provider before system ready");
9322                }
9323
9324                // Make sure that the user who owns this provider is running.  If not,
9325                // we don't want to allow it to run.
9326                if (!isUserRunningLocked(userId, false)) {
9327                    Slog.w(TAG, "Unable to launch app "
9328                            + cpi.applicationInfo.packageName + "/"
9329                            + cpi.applicationInfo.uid + " for provider "
9330                            + name + ": user " + userId + " is stopped");
9331                    return null;
9332                }
9333
9334                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9335                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9336                cpr = mProviderMap.getProviderByClass(comp, userId);
9337                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9338                final boolean firstClass = cpr == null;
9339                if (firstClass) {
9340                    final long ident = Binder.clearCallingIdentity();
9341                    try {
9342                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9343                        ApplicationInfo ai =
9344                            AppGlobals.getPackageManager().
9345                                getApplicationInfo(
9346                                        cpi.applicationInfo.packageName,
9347                                        STOCK_PM_FLAGS, userId);
9348                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9349                        if (ai == null) {
9350                            Slog.w(TAG, "No package info for content provider "
9351                                    + cpi.name);
9352                            return null;
9353                        }
9354                        ai = getAppInfoForUser(ai, userId);
9355                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9356                    } catch (RemoteException ex) {
9357                        // pm is in same process, this will never happen.
9358                    } finally {
9359                        Binder.restoreCallingIdentity(ident);
9360                    }
9361                }
9362
9363                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9364
9365                if (r != null && cpr.canRunHere(r)) {
9366                    // If this is a multiprocess provider, then just return its
9367                    // info and allow the caller to instantiate it.  Only do
9368                    // this if the provider is the same user as the caller's
9369                    // process, or can run as root (so can be in any process).
9370                    return cpr.newHolder(null);
9371                }
9372
9373                if (DEBUG_PROVIDER) {
9374                    RuntimeException e = new RuntimeException("here");
9375                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9376                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9377                }
9378
9379                // This is single process, and our app is now connecting to it.
9380                // See if we are already in the process of launching this
9381                // provider.
9382                final int N = mLaunchingProviders.size();
9383                int i;
9384                for (i=0; i<N; i++) {
9385                    if (mLaunchingProviders.get(i) == cpr) {
9386                        break;
9387                    }
9388                }
9389
9390                // If the provider is not already being launched, then get it
9391                // started.
9392                if (i >= N) {
9393                    final long origId = Binder.clearCallingIdentity();
9394
9395                    try {
9396                        // Content provider is now in use, its package can't be stopped.
9397                        try {
9398                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9399                            AppGlobals.getPackageManager().setPackageStoppedState(
9400                                    cpr.appInfo.packageName, false, userId);
9401                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9402                        } catch (RemoteException e) {
9403                        } catch (IllegalArgumentException e) {
9404                            Slog.w(TAG, "Failed trying to unstop package "
9405                                    + cpr.appInfo.packageName + ": " + e);
9406                        }
9407
9408                        // Use existing process if already started
9409                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9410                        ProcessRecord proc = getProcessRecordLocked(
9411                                cpi.processName, cpr.appInfo.uid, false);
9412                        if (proc != null && proc.thread != null) {
9413                            if (DEBUG_PROVIDER) {
9414                                Slog.d(TAG, "Installing in existing process " + proc);
9415                            }
9416                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9417                            proc.pubProviders.put(cpi.name, cpr);
9418                            try {
9419                                proc.thread.scheduleInstallProvider(cpi);
9420                            } catch (RemoteException e) {
9421                            }
9422                        } else {
9423                            checkTime(startTime, "getContentProviderImpl: before start process");
9424                            proc = startProcessLocked(cpi.processName,
9425                                    cpr.appInfo, false, 0, "content provider",
9426                                    new ComponentName(cpi.applicationInfo.packageName,
9427                                            cpi.name), false, false, false);
9428                            checkTime(startTime, "getContentProviderImpl: after start process");
9429                            if (proc == null) {
9430                                Slog.w(TAG, "Unable to launch app "
9431                                        + cpi.applicationInfo.packageName + "/"
9432                                        + cpi.applicationInfo.uid + " for provider "
9433                                        + name + ": process is bad");
9434                                return null;
9435                            }
9436                        }
9437                        cpr.launchingApp = proc;
9438                        mLaunchingProviders.add(cpr);
9439                    } finally {
9440                        Binder.restoreCallingIdentity(origId);
9441                    }
9442                }
9443
9444                checkTime(startTime, "getContentProviderImpl: updating data structures");
9445
9446                // Make sure the provider is published (the same provider class
9447                // may be published under multiple names).
9448                if (firstClass) {
9449                    mProviderMap.putProviderByClass(comp, cpr);
9450                }
9451
9452                mProviderMap.putProviderByName(name, cpr);
9453                conn = incProviderCountLocked(r, cpr, token, stable);
9454                if (conn != null) {
9455                    conn.waiting = true;
9456                }
9457            }
9458            checkTime(startTime, "getContentProviderImpl: done!");
9459        }
9460
9461        // Wait for the provider to be published...
9462        synchronized (cpr) {
9463            while (cpr.provider == null) {
9464                if (cpr.launchingApp == null) {
9465                    Slog.w(TAG, "Unable to launch app "
9466                            + cpi.applicationInfo.packageName + "/"
9467                            + cpi.applicationInfo.uid + " for provider "
9468                            + name + ": launching app became null");
9469                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9470                            UserHandle.getUserId(cpi.applicationInfo.uid),
9471                            cpi.applicationInfo.packageName,
9472                            cpi.applicationInfo.uid, name);
9473                    return null;
9474                }
9475                try {
9476                    if (DEBUG_MU) {
9477                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9478                                + cpr.launchingApp);
9479                    }
9480                    if (conn != null) {
9481                        conn.waiting = true;
9482                    }
9483                    cpr.wait();
9484                } catch (InterruptedException ex) {
9485                } finally {
9486                    if (conn != null) {
9487                        conn.waiting = false;
9488                    }
9489                }
9490            }
9491        }
9492        return cpr != null ? cpr.newHolder(conn) : null;
9493    }
9494
9495    @Override
9496    public final ContentProviderHolder getContentProvider(
9497            IApplicationThread caller, String name, int userId, boolean stable) {
9498        enforceNotIsolatedCaller("getContentProvider");
9499        if (caller == null) {
9500            String msg = "null IApplicationThread when getting content provider "
9501                    + name;
9502            Slog.w(TAG, msg);
9503            throw new SecurityException(msg);
9504        }
9505        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9506        // with cross-user grant.
9507        return getContentProviderImpl(caller, name, null, stable, userId);
9508    }
9509
9510    public ContentProviderHolder getContentProviderExternal(
9511            String name, int userId, IBinder token) {
9512        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9513            "Do not have permission in call getContentProviderExternal()");
9514        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9515                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9516        return getContentProviderExternalUnchecked(name, token, userId);
9517    }
9518
9519    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9520            IBinder token, int userId) {
9521        return getContentProviderImpl(null, name, token, true, userId);
9522    }
9523
9524    /**
9525     * Drop a content provider from a ProcessRecord's bookkeeping
9526     */
9527    public void removeContentProvider(IBinder connection, boolean stable) {
9528        enforceNotIsolatedCaller("removeContentProvider");
9529        long ident = Binder.clearCallingIdentity();
9530        try {
9531            synchronized (this) {
9532                ContentProviderConnection conn;
9533                try {
9534                    conn = (ContentProviderConnection)connection;
9535                } catch (ClassCastException e) {
9536                    String msg ="removeContentProvider: " + connection
9537                            + " not a ContentProviderConnection";
9538                    Slog.w(TAG, msg);
9539                    throw new IllegalArgumentException(msg);
9540                }
9541                if (conn == null) {
9542                    throw new NullPointerException("connection is null");
9543                }
9544                if (decProviderCountLocked(conn, null, null, stable)) {
9545                    updateOomAdjLocked();
9546                }
9547            }
9548        } finally {
9549            Binder.restoreCallingIdentity(ident);
9550        }
9551    }
9552
9553    public void removeContentProviderExternal(String name, IBinder token) {
9554        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9555            "Do not have permission in call removeContentProviderExternal()");
9556        int userId = UserHandle.getCallingUserId();
9557        long ident = Binder.clearCallingIdentity();
9558        try {
9559            removeContentProviderExternalUnchecked(name, token, userId);
9560        } finally {
9561            Binder.restoreCallingIdentity(ident);
9562        }
9563    }
9564
9565    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9566        synchronized (this) {
9567            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9568            if(cpr == null) {
9569                //remove from mProvidersByClass
9570                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9571                return;
9572            }
9573
9574            //update content provider record entry info
9575            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9576            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9577            if (localCpr.hasExternalProcessHandles()) {
9578                if (localCpr.removeExternalProcessHandleLocked(token)) {
9579                    updateOomAdjLocked();
9580                } else {
9581                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9582                            + " with no external reference for token: "
9583                            + token + ".");
9584                }
9585            } else {
9586                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9587                        + " with no external references.");
9588            }
9589        }
9590    }
9591
9592    public final void publishContentProviders(IApplicationThread caller,
9593            List<ContentProviderHolder> providers) {
9594        if (providers == null) {
9595            return;
9596        }
9597
9598        enforceNotIsolatedCaller("publishContentProviders");
9599        synchronized (this) {
9600            final ProcessRecord r = getRecordForAppLocked(caller);
9601            if (DEBUG_MU)
9602                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9603            if (r == null) {
9604                throw new SecurityException(
9605                        "Unable to find app for caller " + caller
9606                      + " (pid=" + Binder.getCallingPid()
9607                      + ") when publishing content providers");
9608            }
9609
9610            final long origId = Binder.clearCallingIdentity();
9611
9612            final int N = providers.size();
9613            for (int i=0; i<N; i++) {
9614                ContentProviderHolder src = providers.get(i);
9615                if (src == null || src.info == null || src.provider == null) {
9616                    continue;
9617                }
9618                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9619                if (DEBUG_MU)
9620                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9621                if (dst != null) {
9622                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9623                    mProviderMap.putProviderByClass(comp, dst);
9624                    String names[] = dst.info.authority.split(";");
9625                    for (int j = 0; j < names.length; j++) {
9626                        mProviderMap.putProviderByName(names[j], dst);
9627                    }
9628
9629                    int NL = mLaunchingProviders.size();
9630                    int j;
9631                    for (j=0; j<NL; j++) {
9632                        if (mLaunchingProviders.get(j) == dst) {
9633                            mLaunchingProviders.remove(j);
9634                            j--;
9635                            NL--;
9636                        }
9637                    }
9638                    synchronized (dst) {
9639                        dst.provider = src.provider;
9640                        dst.proc = r;
9641                        dst.notifyAll();
9642                    }
9643                    updateOomAdjLocked(r);
9644                }
9645            }
9646
9647            Binder.restoreCallingIdentity(origId);
9648        }
9649    }
9650
9651    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9652        ContentProviderConnection conn;
9653        try {
9654            conn = (ContentProviderConnection)connection;
9655        } catch (ClassCastException e) {
9656            String msg ="refContentProvider: " + connection
9657                    + " not a ContentProviderConnection";
9658            Slog.w(TAG, msg);
9659            throw new IllegalArgumentException(msg);
9660        }
9661        if (conn == null) {
9662            throw new NullPointerException("connection is null");
9663        }
9664
9665        synchronized (this) {
9666            if (stable > 0) {
9667                conn.numStableIncs += stable;
9668            }
9669            stable = conn.stableCount + stable;
9670            if (stable < 0) {
9671                throw new IllegalStateException("stableCount < 0: " + stable);
9672            }
9673
9674            if (unstable > 0) {
9675                conn.numUnstableIncs += unstable;
9676            }
9677            unstable = conn.unstableCount + unstable;
9678            if (unstable < 0) {
9679                throw new IllegalStateException("unstableCount < 0: " + unstable);
9680            }
9681
9682            if ((stable+unstable) <= 0) {
9683                throw new IllegalStateException("ref counts can't go to zero here: stable="
9684                        + stable + " unstable=" + unstable);
9685            }
9686            conn.stableCount = stable;
9687            conn.unstableCount = unstable;
9688            return !conn.dead;
9689        }
9690    }
9691
9692    public void unstableProviderDied(IBinder connection) {
9693        ContentProviderConnection conn;
9694        try {
9695            conn = (ContentProviderConnection)connection;
9696        } catch (ClassCastException e) {
9697            String msg ="refContentProvider: " + connection
9698                    + " not a ContentProviderConnection";
9699            Slog.w(TAG, msg);
9700            throw new IllegalArgumentException(msg);
9701        }
9702        if (conn == null) {
9703            throw new NullPointerException("connection is null");
9704        }
9705
9706        // Safely retrieve the content provider associated with the connection.
9707        IContentProvider provider;
9708        synchronized (this) {
9709            provider = conn.provider.provider;
9710        }
9711
9712        if (provider == null) {
9713            // Um, yeah, we're way ahead of you.
9714            return;
9715        }
9716
9717        // Make sure the caller is being honest with us.
9718        if (provider.asBinder().pingBinder()) {
9719            // Er, no, still looks good to us.
9720            synchronized (this) {
9721                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9722                        + " says " + conn + " died, but we don't agree");
9723                return;
9724            }
9725        }
9726
9727        // Well look at that!  It's dead!
9728        synchronized (this) {
9729            if (conn.provider.provider != provider) {
9730                // But something changed...  good enough.
9731                return;
9732            }
9733
9734            ProcessRecord proc = conn.provider.proc;
9735            if (proc == null || proc.thread == null) {
9736                // Seems like the process is already cleaned up.
9737                return;
9738            }
9739
9740            // As far as we're concerned, this is just like receiving a
9741            // death notification...  just a bit prematurely.
9742            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9743                    + ") early provider death");
9744            final long ident = Binder.clearCallingIdentity();
9745            try {
9746                appDiedLocked(proc);
9747            } finally {
9748                Binder.restoreCallingIdentity(ident);
9749            }
9750        }
9751    }
9752
9753    @Override
9754    public void appNotRespondingViaProvider(IBinder connection) {
9755        enforceCallingPermission(
9756                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9757
9758        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9759        if (conn == null) {
9760            Slog.w(TAG, "ContentProviderConnection is null");
9761            return;
9762        }
9763
9764        final ProcessRecord host = conn.provider.proc;
9765        if (host == null) {
9766            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9767            return;
9768        }
9769
9770        final long token = Binder.clearCallingIdentity();
9771        try {
9772            appNotResponding(host, null, null, false, "ContentProvider not responding");
9773        } finally {
9774            Binder.restoreCallingIdentity(token);
9775        }
9776    }
9777
9778    public final void installSystemProviders() {
9779        List<ProviderInfo> providers;
9780        synchronized (this) {
9781            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9782            providers = generateApplicationProvidersLocked(app);
9783            if (providers != null) {
9784                for (int i=providers.size()-1; i>=0; i--) {
9785                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9786                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9787                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9788                                + ": not system .apk");
9789                        providers.remove(i);
9790                    }
9791                }
9792            }
9793        }
9794        if (providers != null) {
9795            mSystemThread.installSystemProviders(providers);
9796        }
9797
9798        mCoreSettingsObserver = new CoreSettingsObserver(this);
9799
9800        //mUsageStatsService.monitorPackages();
9801    }
9802
9803    /**
9804     * Allows apps to retrieve the MIME type of a URI.
9805     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9806     * users, then it does not need permission to access the ContentProvider.
9807     * Either, it needs cross-user uri grants.
9808     *
9809     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9810     *
9811     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9812     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9813     */
9814    public String getProviderMimeType(Uri uri, int userId) {
9815        enforceNotIsolatedCaller("getProviderMimeType");
9816        final String name = uri.getAuthority();
9817        int callingUid = Binder.getCallingUid();
9818        int callingPid = Binder.getCallingPid();
9819        long ident = 0;
9820        boolean clearedIdentity = false;
9821        userId = unsafeConvertIncomingUser(userId);
9822        if (canClearIdentity(callingPid, callingUid, userId)) {
9823            clearedIdentity = true;
9824            ident = Binder.clearCallingIdentity();
9825        }
9826        ContentProviderHolder holder = null;
9827        try {
9828            holder = getContentProviderExternalUnchecked(name, null, userId);
9829            if (holder != null) {
9830                return holder.provider.getType(uri);
9831            }
9832        } catch (RemoteException e) {
9833            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9834            return null;
9835        } finally {
9836            // We need to clear the identity to call removeContentProviderExternalUnchecked
9837            if (!clearedIdentity) {
9838                ident = Binder.clearCallingIdentity();
9839            }
9840            try {
9841                if (holder != null) {
9842                    removeContentProviderExternalUnchecked(name, null, userId);
9843                }
9844            } finally {
9845                Binder.restoreCallingIdentity(ident);
9846            }
9847        }
9848
9849        return null;
9850    }
9851
9852    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9853        if (UserHandle.getUserId(callingUid) == userId) {
9854            return true;
9855        }
9856        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9857                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9858                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9859                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9860                return true;
9861        }
9862        return false;
9863    }
9864
9865    // =========================================================
9866    // GLOBAL MANAGEMENT
9867    // =========================================================
9868
9869    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9870            boolean isolated, int isolatedUid) {
9871        String proc = customProcess != null ? customProcess : info.processName;
9872        BatteryStatsImpl.Uid.Proc ps = null;
9873        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9874        int uid = info.uid;
9875        if (isolated) {
9876            if (isolatedUid == 0) {
9877                int userId = UserHandle.getUserId(uid);
9878                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9879                while (true) {
9880                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9881                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9882                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9883                    }
9884                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9885                    mNextIsolatedProcessUid++;
9886                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9887                        // No process for this uid, use it.
9888                        break;
9889                    }
9890                    stepsLeft--;
9891                    if (stepsLeft <= 0) {
9892                        return null;
9893                    }
9894                }
9895            } else {
9896                // Special case for startIsolatedProcess (internal only), where
9897                // the uid of the isolated process is specified by the caller.
9898                uid = isolatedUid;
9899            }
9900        }
9901        return new ProcessRecord(stats, info, proc, uid);
9902    }
9903
9904    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9905            String abiOverride) {
9906        ProcessRecord app;
9907        if (!isolated) {
9908            app = getProcessRecordLocked(info.processName, info.uid, true);
9909        } else {
9910            app = null;
9911        }
9912
9913        if (app == null) {
9914            app = newProcessRecordLocked(info, null, isolated, 0);
9915            mProcessNames.put(info.processName, app.uid, app);
9916            if (isolated) {
9917                mIsolatedProcesses.put(app.uid, app);
9918            }
9919            updateLruProcessLocked(app, false, null);
9920            updateOomAdjLocked();
9921        }
9922
9923        // This package really, really can not be stopped.
9924        try {
9925            AppGlobals.getPackageManager().setPackageStoppedState(
9926                    info.packageName, false, UserHandle.getUserId(app.uid));
9927        } catch (RemoteException e) {
9928        } catch (IllegalArgumentException e) {
9929            Slog.w(TAG, "Failed trying to unstop package "
9930                    + info.packageName + ": " + e);
9931        }
9932
9933        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9934                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9935            app.persistent = true;
9936            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9937        }
9938        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9939            mPersistentStartingProcesses.add(app);
9940            startProcessLocked(app, "added application", app.processName, abiOverride,
9941                    null /* entryPoint */, null /* entryPointArgs */);
9942        }
9943
9944        return app;
9945    }
9946
9947    public void unhandledBack() {
9948        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9949                "unhandledBack()");
9950
9951        synchronized(this) {
9952            final long origId = Binder.clearCallingIdentity();
9953            try {
9954                getFocusedStack().unhandledBackLocked();
9955            } finally {
9956                Binder.restoreCallingIdentity(origId);
9957            }
9958        }
9959    }
9960
9961    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9962        enforceNotIsolatedCaller("openContentUri");
9963        final int userId = UserHandle.getCallingUserId();
9964        String name = uri.getAuthority();
9965        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9966        ParcelFileDescriptor pfd = null;
9967        if (cph != null) {
9968            // We record the binder invoker's uid in thread-local storage before
9969            // going to the content provider to open the file.  Later, in the code
9970            // that handles all permissions checks, we look for this uid and use
9971            // that rather than the Activity Manager's own uid.  The effect is that
9972            // we do the check against the caller's permissions even though it looks
9973            // to the content provider like the Activity Manager itself is making
9974            // the request.
9975            Binder token = new Binder();
9976            sCallerIdentity.set(new Identity(
9977                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9978            try {
9979                pfd = cph.provider.openFile(null, uri, "r", null, token);
9980            } catch (FileNotFoundException e) {
9981                // do nothing; pfd will be returned null
9982            } finally {
9983                // Ensure that whatever happens, we clean up the identity state
9984                sCallerIdentity.remove();
9985            }
9986
9987            // We've got the fd now, so we're done with the provider.
9988            removeContentProviderExternalUnchecked(name, null, userId);
9989        } else {
9990            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9991        }
9992        return pfd;
9993    }
9994
9995    // Actually is sleeping or shutting down or whatever else in the future
9996    // is an inactive state.
9997    public boolean isSleepingOrShuttingDown() {
9998        return isSleeping() || mShuttingDown;
9999    }
10000
10001    public boolean isSleeping() {
10002        return mSleeping;
10003    }
10004
10005    void onWakefulnessChanged(int wakefulness) {
10006        synchronized(this) {
10007            mWakefulness = wakefulness;
10008            updateSleepIfNeededLocked();
10009        }
10010    }
10011
10012    void finishRunningVoiceLocked() {
10013        if (mRunningVoice) {
10014            mRunningVoice = false;
10015            updateSleepIfNeededLocked();
10016        }
10017    }
10018
10019    void updateSleepIfNeededLocked() {
10020        if (mSleeping && !shouldSleepLocked()) {
10021            mSleeping = false;
10022            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10023        } else if (!mSleeping && shouldSleepLocked()) {
10024            mSleeping = true;
10025            mStackSupervisor.goingToSleepLocked();
10026
10027            // Initialize the wake times of all processes.
10028            checkExcessivePowerUsageLocked(false);
10029            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10030            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10031            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10032        }
10033    }
10034
10035    private boolean shouldSleepLocked() {
10036        // Resume applications while running a voice interactor.
10037        if (mRunningVoice) {
10038            return false;
10039        }
10040
10041        switch (mWakefulness) {
10042            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10043            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10044                // If we're interactive but applications are already paused then defer
10045                // resuming them until the lock screen is hidden.
10046                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10047            case PowerManagerInternal.WAKEFULNESS_DOZING:
10048                // If we're dozing then pause applications whenever the lock screen is shown.
10049                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10050            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10051            default:
10052                // If we're asleep then pause applications unconditionally.
10053                return true;
10054        }
10055    }
10056
10057    /** Pokes the task persister. */
10058    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10059        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10060            // Never persist the home stack.
10061            return;
10062        }
10063        mTaskPersister.wakeup(task, flush);
10064    }
10065
10066    /** Notifies all listeners when the task stack has changed. */
10067    void notifyTaskStackChangedLocked() {
10068        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10069        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10070        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10071    }
10072
10073    @Override
10074    public boolean shutdown(int timeout) {
10075        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10076                != PackageManager.PERMISSION_GRANTED) {
10077            throw new SecurityException("Requires permission "
10078                    + android.Manifest.permission.SHUTDOWN);
10079        }
10080
10081        boolean timedout = false;
10082
10083        synchronized(this) {
10084            mShuttingDown = true;
10085            updateEventDispatchingLocked();
10086            timedout = mStackSupervisor.shutdownLocked(timeout);
10087        }
10088
10089        mAppOpsService.shutdown();
10090        if (mUsageStatsService != null) {
10091            mUsageStatsService.prepareShutdown();
10092        }
10093        mBatteryStatsService.shutdown();
10094        synchronized (this) {
10095            mProcessStats.shutdownLocked();
10096            notifyTaskPersisterLocked(null, true);
10097        }
10098
10099        return timedout;
10100    }
10101
10102    public final void activitySlept(IBinder token) {
10103        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10104
10105        final long origId = Binder.clearCallingIdentity();
10106
10107        synchronized (this) {
10108            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10109            if (r != null) {
10110                mStackSupervisor.activitySleptLocked(r);
10111            }
10112        }
10113
10114        Binder.restoreCallingIdentity(origId);
10115    }
10116
10117    private String lockScreenShownToString() {
10118        switch (mLockScreenShown) {
10119            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10120            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10121            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10122            default: return "Unknown=" + mLockScreenShown;
10123        }
10124    }
10125
10126    void logLockScreen(String msg) {
10127        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10128                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10129                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10130                + " mSleeping=" + mSleeping);
10131    }
10132
10133    void startRunningVoiceLocked() {
10134        if (!mRunningVoice) {
10135            mRunningVoice = true;
10136            updateSleepIfNeededLocked();
10137        }
10138    }
10139
10140    private void updateEventDispatchingLocked() {
10141        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10142    }
10143
10144    public void setLockScreenShown(boolean shown) {
10145        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10146                != PackageManager.PERMISSION_GRANTED) {
10147            throw new SecurityException("Requires permission "
10148                    + android.Manifest.permission.DEVICE_POWER);
10149        }
10150
10151        synchronized(this) {
10152            long ident = Binder.clearCallingIdentity();
10153            try {
10154                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10155                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10156                updateSleepIfNeededLocked();
10157            } finally {
10158                Binder.restoreCallingIdentity(ident);
10159            }
10160        }
10161    }
10162
10163    @Override
10164    public void stopAppSwitches() {
10165        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10166                != PackageManager.PERMISSION_GRANTED) {
10167            throw new SecurityException("Requires permission "
10168                    + android.Manifest.permission.STOP_APP_SWITCHES);
10169        }
10170
10171        synchronized(this) {
10172            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10173                    + APP_SWITCH_DELAY_TIME;
10174            mDidAppSwitch = false;
10175            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10176            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10177            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10178        }
10179    }
10180
10181    public void resumeAppSwitches() {
10182        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10183                != PackageManager.PERMISSION_GRANTED) {
10184            throw new SecurityException("Requires permission "
10185                    + android.Manifest.permission.STOP_APP_SWITCHES);
10186        }
10187
10188        synchronized(this) {
10189            // Note that we don't execute any pending app switches... we will
10190            // let those wait until either the timeout, or the next start
10191            // activity request.
10192            mAppSwitchesAllowedTime = 0;
10193        }
10194    }
10195
10196    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10197            int callingPid, int callingUid, String name) {
10198        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10199            return true;
10200        }
10201
10202        int perm = checkComponentPermission(
10203                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10204                sourceUid, -1, true);
10205        if (perm == PackageManager.PERMISSION_GRANTED) {
10206            return true;
10207        }
10208
10209        // If the actual IPC caller is different from the logical source, then
10210        // also see if they are allowed to control app switches.
10211        if (callingUid != -1 && callingUid != sourceUid) {
10212            perm = checkComponentPermission(
10213                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10214                    callingUid, -1, true);
10215            if (perm == PackageManager.PERMISSION_GRANTED) {
10216                return true;
10217            }
10218        }
10219
10220        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10221        return false;
10222    }
10223
10224    public void setDebugApp(String packageName, boolean waitForDebugger,
10225            boolean persistent) {
10226        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10227                "setDebugApp()");
10228
10229        long ident = Binder.clearCallingIdentity();
10230        try {
10231            // Note that this is not really thread safe if there are multiple
10232            // callers into it at the same time, but that's not a situation we
10233            // care about.
10234            if (persistent) {
10235                final ContentResolver resolver = mContext.getContentResolver();
10236                Settings.Global.putString(
10237                    resolver, Settings.Global.DEBUG_APP,
10238                    packageName);
10239                Settings.Global.putInt(
10240                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10241                    waitForDebugger ? 1 : 0);
10242            }
10243
10244            synchronized (this) {
10245                if (!persistent) {
10246                    mOrigDebugApp = mDebugApp;
10247                    mOrigWaitForDebugger = mWaitForDebugger;
10248                }
10249                mDebugApp = packageName;
10250                mWaitForDebugger = waitForDebugger;
10251                mDebugTransient = !persistent;
10252                if (packageName != null) {
10253                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10254                            false, UserHandle.USER_ALL, "set debug app");
10255                }
10256            }
10257        } finally {
10258            Binder.restoreCallingIdentity(ident);
10259        }
10260    }
10261
10262    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10263        synchronized (this) {
10264            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10265            if (!isDebuggable) {
10266                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10267                    throw new SecurityException("Process not debuggable: " + app.packageName);
10268                }
10269            }
10270
10271            mOpenGlTraceApp = processName;
10272        }
10273    }
10274
10275    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10276        synchronized (this) {
10277            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10278            if (!isDebuggable) {
10279                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10280                    throw new SecurityException("Process not debuggable: " + app.packageName);
10281                }
10282            }
10283            mProfileApp = processName;
10284            mProfileFile = profilerInfo.profileFile;
10285            if (mProfileFd != null) {
10286                try {
10287                    mProfileFd.close();
10288                } catch (IOException e) {
10289                }
10290                mProfileFd = null;
10291            }
10292            mProfileFd = profilerInfo.profileFd;
10293            mSamplingInterval = profilerInfo.samplingInterval;
10294            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10295            mProfileType = 0;
10296        }
10297    }
10298
10299    @Override
10300    public void setAlwaysFinish(boolean enabled) {
10301        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10302                "setAlwaysFinish()");
10303
10304        Settings.Global.putInt(
10305                mContext.getContentResolver(),
10306                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10307
10308        synchronized (this) {
10309            mAlwaysFinishActivities = enabled;
10310        }
10311    }
10312
10313    @Override
10314    public void setActivityController(IActivityController controller) {
10315        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10316                "setActivityController()");
10317        synchronized (this) {
10318            mController = controller;
10319            Watchdog.getInstance().setActivityController(controller);
10320        }
10321    }
10322
10323    @Override
10324    public void setUserIsMonkey(boolean userIsMonkey) {
10325        synchronized (this) {
10326            synchronized (mPidsSelfLocked) {
10327                final int callingPid = Binder.getCallingPid();
10328                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10329                if (precessRecord == null) {
10330                    throw new SecurityException("Unknown process: " + callingPid);
10331                }
10332                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10333                    throw new SecurityException("Only an instrumentation process "
10334                            + "with a UiAutomation can call setUserIsMonkey");
10335                }
10336            }
10337            mUserIsMonkey = userIsMonkey;
10338        }
10339    }
10340
10341    @Override
10342    public boolean isUserAMonkey() {
10343        synchronized (this) {
10344            // If there is a controller also implies the user is a monkey.
10345            return (mUserIsMonkey || mController != null);
10346        }
10347    }
10348
10349    public void requestBugReport() {
10350        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10351        SystemProperties.set("ctl.start", "bugreport");
10352    }
10353
10354    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10355        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10356    }
10357
10358    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10359        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10360            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10361        }
10362        return KEY_DISPATCHING_TIMEOUT;
10363    }
10364
10365    @Override
10366    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10367        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10368                != PackageManager.PERMISSION_GRANTED) {
10369            throw new SecurityException("Requires permission "
10370                    + android.Manifest.permission.FILTER_EVENTS);
10371        }
10372        ProcessRecord proc;
10373        long timeout;
10374        synchronized (this) {
10375            synchronized (mPidsSelfLocked) {
10376                proc = mPidsSelfLocked.get(pid);
10377            }
10378            timeout = getInputDispatchingTimeoutLocked(proc);
10379        }
10380
10381        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10382            return -1;
10383        }
10384
10385        return timeout;
10386    }
10387
10388    /**
10389     * Handle input dispatching timeouts.
10390     * Returns whether input dispatching should be aborted or not.
10391     */
10392    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10393            final ActivityRecord activity, final ActivityRecord parent,
10394            final boolean aboveSystem, String reason) {
10395        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10396                != PackageManager.PERMISSION_GRANTED) {
10397            throw new SecurityException("Requires permission "
10398                    + android.Manifest.permission.FILTER_EVENTS);
10399        }
10400
10401        final String annotation;
10402        if (reason == null) {
10403            annotation = "Input dispatching timed out";
10404        } else {
10405            annotation = "Input dispatching timed out (" + reason + ")";
10406        }
10407
10408        if (proc != null) {
10409            synchronized (this) {
10410                if (proc.debugging) {
10411                    return false;
10412                }
10413
10414                if (mDidDexOpt) {
10415                    // Give more time since we were dexopting.
10416                    mDidDexOpt = false;
10417                    return false;
10418                }
10419
10420                if (proc.instrumentationClass != null) {
10421                    Bundle info = new Bundle();
10422                    info.putString("shortMsg", "keyDispatchingTimedOut");
10423                    info.putString("longMsg", annotation);
10424                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10425                    return true;
10426                }
10427            }
10428            mHandler.post(new Runnable() {
10429                @Override
10430                public void run() {
10431                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10432                }
10433            });
10434        }
10435
10436        return true;
10437    }
10438
10439    public Bundle getAssistContextExtras(int requestType) {
10440        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10441                UserHandle.getCallingUserId());
10442        if (pae == null) {
10443            return null;
10444        }
10445        synchronized (pae) {
10446            while (!pae.haveResult) {
10447                try {
10448                    pae.wait();
10449                } catch (InterruptedException e) {
10450                }
10451            }
10452            if (pae.result != null) {
10453                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10454            }
10455        }
10456        synchronized (this) {
10457            mPendingAssistExtras.remove(pae);
10458            mHandler.removeCallbacks(pae);
10459        }
10460        return pae.extras;
10461    }
10462
10463    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10464            int userHandle) {
10465        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10466                "getAssistContextExtras()");
10467        PendingAssistExtras pae;
10468        Bundle extras = new Bundle();
10469        synchronized (this) {
10470            ActivityRecord activity = getFocusedStack().mResumedActivity;
10471            if (activity == null) {
10472                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10473                return null;
10474            }
10475            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10476            if (activity.app == null || activity.app.thread == null) {
10477                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10478                return null;
10479            }
10480            if (activity.app.pid == Binder.getCallingPid()) {
10481                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10482                return null;
10483            }
10484            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10485            try {
10486                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10487                        requestType);
10488                mPendingAssistExtras.add(pae);
10489                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10490            } catch (RemoteException e) {
10491                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10492                return null;
10493            }
10494            return pae;
10495        }
10496    }
10497
10498    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10499        PendingAssistExtras pae = (PendingAssistExtras)token;
10500        synchronized (pae) {
10501            pae.result = extras;
10502            pae.haveResult = true;
10503            pae.notifyAll();
10504            if (pae.intent == null) {
10505                // Caller is just waiting for the result.
10506                return;
10507            }
10508        }
10509
10510        // We are now ready to launch the assist activity.
10511        synchronized (this) {
10512            boolean exists = mPendingAssistExtras.remove(pae);
10513            mHandler.removeCallbacks(pae);
10514            if (!exists) {
10515                // Timed out.
10516                return;
10517            }
10518        }
10519        pae.intent.replaceExtras(extras);
10520        if (pae.hint != null) {
10521            pae.intent.putExtra(pae.hint, true);
10522        }
10523        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10524                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10525                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10526        closeSystemDialogs("assist");
10527        try {
10528            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10529        } catch (ActivityNotFoundException e) {
10530            Slog.w(TAG, "No activity to handle assist action.", e);
10531        }
10532    }
10533
10534    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10535        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10536    }
10537
10538    public void registerProcessObserver(IProcessObserver observer) {
10539        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10540                "registerProcessObserver()");
10541        synchronized (this) {
10542            mProcessObservers.register(observer);
10543        }
10544    }
10545
10546    @Override
10547    public void unregisterProcessObserver(IProcessObserver observer) {
10548        synchronized (this) {
10549            mProcessObservers.unregister(observer);
10550        }
10551    }
10552
10553    @Override
10554    public boolean convertFromTranslucent(IBinder token) {
10555        final long origId = Binder.clearCallingIdentity();
10556        try {
10557            synchronized (this) {
10558                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10559                if (r == null) {
10560                    return false;
10561                }
10562                final boolean translucentChanged = r.changeWindowTranslucency(true);
10563                if (translucentChanged) {
10564                    r.task.stack.releaseBackgroundResources();
10565                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10566                }
10567                mWindowManager.setAppFullscreen(token, true);
10568                return translucentChanged;
10569            }
10570        } finally {
10571            Binder.restoreCallingIdentity(origId);
10572        }
10573    }
10574
10575    @Override
10576    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10577        final long origId = Binder.clearCallingIdentity();
10578        try {
10579            synchronized (this) {
10580                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10581                if (r == null) {
10582                    return false;
10583                }
10584                int index = r.task.mActivities.lastIndexOf(r);
10585                if (index > 0) {
10586                    ActivityRecord under = r.task.mActivities.get(index - 1);
10587                    under.returningOptions = options;
10588                }
10589                final boolean translucentChanged = r.changeWindowTranslucency(false);
10590                if (translucentChanged) {
10591                    r.task.stack.convertToTranslucent(r);
10592                }
10593                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10594                mWindowManager.setAppFullscreen(token, false);
10595                return translucentChanged;
10596            }
10597        } finally {
10598            Binder.restoreCallingIdentity(origId);
10599        }
10600    }
10601
10602    @Override
10603    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10604        final long origId = Binder.clearCallingIdentity();
10605        try {
10606            synchronized (this) {
10607                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10608                if (r != null) {
10609                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10610                }
10611            }
10612            return false;
10613        } finally {
10614            Binder.restoreCallingIdentity(origId);
10615        }
10616    }
10617
10618    @Override
10619    public boolean isBackgroundVisibleBehind(IBinder token) {
10620        final long origId = Binder.clearCallingIdentity();
10621        try {
10622            synchronized (this) {
10623                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10624                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10625                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10626                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10627                return visible;
10628            }
10629        } finally {
10630            Binder.restoreCallingIdentity(origId);
10631        }
10632    }
10633
10634    @Override
10635    public ActivityOptions getActivityOptions(IBinder token) {
10636        final long origId = Binder.clearCallingIdentity();
10637        try {
10638            synchronized (this) {
10639                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10640                if (r != null) {
10641                    final ActivityOptions activityOptions = r.pendingOptions;
10642                    r.pendingOptions = null;
10643                    return activityOptions;
10644                }
10645                return null;
10646            }
10647        } finally {
10648            Binder.restoreCallingIdentity(origId);
10649        }
10650    }
10651
10652    @Override
10653    public void setImmersive(IBinder token, boolean immersive) {
10654        synchronized(this) {
10655            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10656            if (r == null) {
10657                throw new IllegalArgumentException();
10658            }
10659            r.immersive = immersive;
10660
10661            // update associated state if we're frontmost
10662            if (r == mFocusedActivity) {
10663                if (DEBUG_IMMERSIVE) {
10664                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10665                }
10666                applyUpdateLockStateLocked(r);
10667            }
10668        }
10669    }
10670
10671    @Override
10672    public boolean isImmersive(IBinder token) {
10673        synchronized (this) {
10674            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10675            if (r == null) {
10676                throw new IllegalArgumentException();
10677            }
10678            return r.immersive;
10679        }
10680    }
10681
10682    public boolean isTopActivityImmersive() {
10683        enforceNotIsolatedCaller("startActivity");
10684        synchronized (this) {
10685            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10686            return (r != null) ? r.immersive : false;
10687        }
10688    }
10689
10690    @Override
10691    public boolean isTopOfTask(IBinder token) {
10692        synchronized (this) {
10693            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10694            if (r == null) {
10695                throw new IllegalArgumentException();
10696            }
10697            return r.task.getTopActivity() == r;
10698        }
10699    }
10700
10701    public final void enterSafeMode() {
10702        synchronized(this) {
10703            // It only makes sense to do this before the system is ready
10704            // and started launching other packages.
10705            if (!mSystemReady) {
10706                try {
10707                    AppGlobals.getPackageManager().enterSafeMode();
10708                } catch (RemoteException e) {
10709                }
10710            }
10711
10712            mSafeMode = true;
10713        }
10714    }
10715
10716    public final void showSafeModeOverlay() {
10717        View v = LayoutInflater.from(mContext).inflate(
10718                com.android.internal.R.layout.safe_mode, null);
10719        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10720        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10721        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10722        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10723        lp.gravity = Gravity.BOTTOM | Gravity.START;
10724        lp.format = v.getBackground().getOpacity();
10725        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10726                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10727        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10728        ((WindowManager)mContext.getSystemService(
10729                Context.WINDOW_SERVICE)).addView(v, lp);
10730    }
10731
10732    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10733        if (!(sender instanceof PendingIntentRecord)) {
10734            return;
10735        }
10736        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10737        synchronized (stats) {
10738            if (mBatteryStatsService.isOnBattery()) {
10739                mBatteryStatsService.enforceCallingPermission();
10740                PendingIntentRecord rec = (PendingIntentRecord)sender;
10741                int MY_UID = Binder.getCallingUid();
10742                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10743                BatteryStatsImpl.Uid.Pkg pkg =
10744                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10745                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10746                pkg.incWakeupsLocked();
10747            }
10748        }
10749    }
10750
10751    public boolean killPids(int[] pids, String pReason, boolean secure) {
10752        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10753            throw new SecurityException("killPids only available to the system");
10754        }
10755        String reason = (pReason == null) ? "Unknown" : pReason;
10756        // XXX Note: don't acquire main activity lock here, because the window
10757        // manager calls in with its locks held.
10758
10759        boolean killed = false;
10760        synchronized (mPidsSelfLocked) {
10761            int[] types = new int[pids.length];
10762            int worstType = 0;
10763            for (int i=0; i<pids.length; i++) {
10764                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10765                if (proc != null) {
10766                    int type = proc.setAdj;
10767                    types[i] = type;
10768                    if (type > worstType) {
10769                        worstType = type;
10770                    }
10771                }
10772            }
10773
10774            // If the worst oom_adj is somewhere in the cached proc LRU range,
10775            // then constrain it so we will kill all cached procs.
10776            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10777                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10778                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10779            }
10780
10781            // If this is not a secure call, don't let it kill processes that
10782            // are important.
10783            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10784                worstType = ProcessList.SERVICE_ADJ;
10785            }
10786
10787            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10788            for (int i=0; i<pids.length; i++) {
10789                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10790                if (proc == null) {
10791                    continue;
10792                }
10793                int adj = proc.setAdj;
10794                if (adj >= worstType && !proc.killedByAm) {
10795                    proc.kill(reason, true);
10796                    killed = true;
10797                }
10798            }
10799        }
10800        return killed;
10801    }
10802
10803    @Override
10804    public void killUid(int uid, String reason) {
10805        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10806            throw new SecurityException("killUid only available to the system");
10807        }
10808        synchronized (this) {
10809            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10810                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10811                    reason != null ? reason : "kill uid");
10812        }
10813    }
10814
10815    @Override
10816    public boolean killProcessesBelowForeground(String reason) {
10817        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10818            throw new SecurityException("killProcessesBelowForeground() only available to system");
10819        }
10820
10821        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10822    }
10823
10824    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10825        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10826            throw new SecurityException("killProcessesBelowAdj() only available to system");
10827        }
10828
10829        boolean killed = false;
10830        synchronized (mPidsSelfLocked) {
10831            final int size = mPidsSelfLocked.size();
10832            for (int i = 0; i < size; i++) {
10833                final int pid = mPidsSelfLocked.keyAt(i);
10834                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10835                if (proc == null) continue;
10836
10837                final int adj = proc.setAdj;
10838                if (adj > belowAdj && !proc.killedByAm) {
10839                    proc.kill(reason, true);
10840                    killed = true;
10841                }
10842            }
10843        }
10844        return killed;
10845    }
10846
10847    @Override
10848    public void hang(final IBinder who, boolean allowRestart) {
10849        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10850                != PackageManager.PERMISSION_GRANTED) {
10851            throw new SecurityException("Requires permission "
10852                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10853        }
10854
10855        final IBinder.DeathRecipient death = new DeathRecipient() {
10856            @Override
10857            public void binderDied() {
10858                synchronized (this) {
10859                    notifyAll();
10860                }
10861            }
10862        };
10863
10864        try {
10865            who.linkToDeath(death, 0);
10866        } catch (RemoteException e) {
10867            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10868            return;
10869        }
10870
10871        synchronized (this) {
10872            Watchdog.getInstance().setAllowRestart(allowRestart);
10873            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10874            synchronized (death) {
10875                while (who.isBinderAlive()) {
10876                    try {
10877                        death.wait();
10878                    } catch (InterruptedException e) {
10879                    }
10880                }
10881            }
10882            Watchdog.getInstance().setAllowRestart(true);
10883        }
10884    }
10885
10886    @Override
10887    public void restart() {
10888        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10889                != PackageManager.PERMISSION_GRANTED) {
10890            throw new SecurityException("Requires permission "
10891                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10892        }
10893
10894        Log.i(TAG, "Sending shutdown broadcast...");
10895
10896        BroadcastReceiver br = new BroadcastReceiver() {
10897            @Override public void onReceive(Context context, Intent intent) {
10898                // Now the broadcast is done, finish up the low-level shutdown.
10899                Log.i(TAG, "Shutting down activity manager...");
10900                shutdown(10000);
10901                Log.i(TAG, "Shutdown complete, restarting!");
10902                Process.killProcess(Process.myPid());
10903                System.exit(10);
10904            }
10905        };
10906
10907        // First send the high-level shut down broadcast.
10908        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10909        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10910        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10911        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10912        mContext.sendOrderedBroadcastAsUser(intent,
10913                UserHandle.ALL, null, br, mHandler, 0, null, null);
10914        */
10915        br.onReceive(mContext, intent);
10916    }
10917
10918    private long getLowRamTimeSinceIdle(long now) {
10919        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10920    }
10921
10922    @Override
10923    public void performIdleMaintenance() {
10924        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10925                != PackageManager.PERMISSION_GRANTED) {
10926            throw new SecurityException("Requires permission "
10927                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10928        }
10929
10930        synchronized (this) {
10931            final long now = SystemClock.uptimeMillis();
10932            final long timeSinceLastIdle = now - mLastIdleTime;
10933            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10934            mLastIdleTime = now;
10935            mLowRamTimeSinceLastIdle = 0;
10936            if (mLowRamStartTime != 0) {
10937                mLowRamStartTime = now;
10938            }
10939
10940            StringBuilder sb = new StringBuilder(128);
10941            sb.append("Idle maintenance over ");
10942            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10943            sb.append(" low RAM for ");
10944            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10945            Slog.i(TAG, sb.toString());
10946
10947            // If at least 1/3 of our time since the last idle period has been spent
10948            // with RAM low, then we want to kill processes.
10949            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10950
10951            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10952                ProcessRecord proc = mLruProcesses.get(i);
10953                if (proc.notCachedSinceIdle) {
10954                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10955                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10956                        if (doKilling && proc.initialIdlePss != 0
10957                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10958                            sb = new StringBuilder(128);
10959                            sb.append("Kill");
10960                            sb.append(proc.processName);
10961                            sb.append(" in idle maint: pss=");
10962                            sb.append(proc.lastPss);
10963                            sb.append(", initialPss=");
10964                            sb.append(proc.initialIdlePss);
10965                            sb.append(", period=");
10966                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10967                            sb.append(", lowRamPeriod=");
10968                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10969                            Slog.wtfQuiet(TAG, sb.toString());
10970                            proc.kill("idle maint (pss " + proc.lastPss
10971                                    + " from " + proc.initialIdlePss + ")", true);
10972                        }
10973                    }
10974                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10975                    proc.notCachedSinceIdle = true;
10976                    proc.initialIdlePss = 0;
10977                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10978                            mTestPssMode, isSleeping(), now);
10979                }
10980            }
10981
10982            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10983            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10984        }
10985    }
10986
10987    private void retrieveSettings() {
10988        final ContentResolver resolver = mContext.getContentResolver();
10989        String debugApp = Settings.Global.getString(
10990            resolver, Settings.Global.DEBUG_APP);
10991        boolean waitForDebugger = Settings.Global.getInt(
10992            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10993        boolean alwaysFinishActivities = Settings.Global.getInt(
10994            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10995        boolean forceRtl = Settings.Global.getInt(
10996                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10997        // Transfer any global setting for forcing RTL layout, into a System Property
10998        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10999
11000        Configuration configuration = new Configuration();
11001        Settings.System.getConfiguration(resolver, configuration);
11002        if (forceRtl) {
11003            // This will take care of setting the correct layout direction flags
11004            configuration.setLayoutDirection(configuration.locale);
11005        }
11006
11007        synchronized (this) {
11008            mDebugApp = mOrigDebugApp = debugApp;
11009            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11010            mAlwaysFinishActivities = alwaysFinishActivities;
11011            // This happens before any activities are started, so we can
11012            // change mConfiguration in-place.
11013            updateConfigurationLocked(configuration, null, false, true);
11014            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11015        }
11016    }
11017
11018    /** Loads resources after the current configuration has been set. */
11019    private void loadResourcesOnSystemReady() {
11020        final Resources res = mContext.getResources();
11021        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11022        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11023        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11024    }
11025
11026    public boolean testIsSystemReady() {
11027        // no need to synchronize(this) just to read & return the value
11028        return mSystemReady;
11029    }
11030
11031    private static File getCalledPreBootReceiversFile() {
11032        File dataDir = Environment.getDataDirectory();
11033        File systemDir = new File(dataDir, "system");
11034        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11035        return fname;
11036    }
11037
11038    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11039        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11040        File file = getCalledPreBootReceiversFile();
11041        FileInputStream fis = null;
11042        try {
11043            fis = new FileInputStream(file);
11044            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11045            int fvers = dis.readInt();
11046            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11047                String vers = dis.readUTF();
11048                String codename = dis.readUTF();
11049                String build = dis.readUTF();
11050                if (android.os.Build.VERSION.RELEASE.equals(vers)
11051                        && android.os.Build.VERSION.CODENAME.equals(codename)
11052                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11053                    int num = dis.readInt();
11054                    while (num > 0) {
11055                        num--;
11056                        String pkg = dis.readUTF();
11057                        String cls = dis.readUTF();
11058                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11059                    }
11060                }
11061            }
11062        } catch (FileNotFoundException e) {
11063        } catch (IOException e) {
11064            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11065        } finally {
11066            if (fis != null) {
11067                try {
11068                    fis.close();
11069                } catch (IOException e) {
11070                }
11071            }
11072        }
11073        return lastDoneReceivers;
11074    }
11075
11076    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11077        File file = getCalledPreBootReceiversFile();
11078        FileOutputStream fos = null;
11079        DataOutputStream dos = null;
11080        try {
11081            fos = new FileOutputStream(file);
11082            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11083            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11084            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11085            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11086            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11087            dos.writeInt(list.size());
11088            for (int i=0; i<list.size(); i++) {
11089                dos.writeUTF(list.get(i).getPackageName());
11090                dos.writeUTF(list.get(i).getClassName());
11091            }
11092        } catch (IOException e) {
11093            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11094            file.delete();
11095        } finally {
11096            FileUtils.sync(fos);
11097            if (dos != null) {
11098                try {
11099                    dos.close();
11100                } catch (IOException e) {
11101                    // TODO Auto-generated catch block
11102                    e.printStackTrace();
11103                }
11104            }
11105        }
11106    }
11107
11108    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11109            ArrayList<ComponentName> doneReceivers, int userId) {
11110        boolean waitingUpdate = false;
11111        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11112        List<ResolveInfo> ris = null;
11113        try {
11114            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11115                    intent, null, 0, userId);
11116        } catch (RemoteException e) {
11117        }
11118        if (ris != null) {
11119            for (int i=ris.size()-1; i>=0; i--) {
11120                if ((ris.get(i).activityInfo.applicationInfo.flags
11121                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11122                    ris.remove(i);
11123                }
11124            }
11125            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11126
11127            // For User 0, load the version number. When delivering to a new user, deliver
11128            // to all receivers.
11129            if (userId == UserHandle.USER_OWNER) {
11130                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11131                for (int i=0; i<ris.size(); i++) {
11132                    ActivityInfo ai = ris.get(i).activityInfo;
11133                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11134                    if (lastDoneReceivers.contains(comp)) {
11135                        // We already did the pre boot receiver for this app with the current
11136                        // platform version, so don't do it again...
11137                        ris.remove(i);
11138                        i--;
11139                        // ...however, do keep it as one that has been done, so we don't
11140                        // forget about it when rewriting the file of last done receivers.
11141                        doneReceivers.add(comp);
11142                    }
11143                }
11144            }
11145
11146            // If primary user, send broadcast to all available users, else just to userId
11147            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11148                    : new int[] { userId };
11149            for (int i = 0; i < ris.size(); i++) {
11150                ActivityInfo ai = ris.get(i).activityInfo;
11151                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11152                doneReceivers.add(comp);
11153                intent.setComponent(comp);
11154                for (int j=0; j<users.length; j++) {
11155                    IIntentReceiver finisher = null;
11156                    // On last receiver and user, set up a completion callback
11157                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11158                        finisher = new IIntentReceiver.Stub() {
11159                            public void performReceive(Intent intent, int resultCode,
11160                                    String data, Bundle extras, boolean ordered,
11161                                    boolean sticky, int sendingUser) {
11162                                // The raw IIntentReceiver interface is called
11163                                // with the AM lock held, so redispatch to
11164                                // execute our code without the lock.
11165                                mHandler.post(onFinishCallback);
11166                            }
11167                        };
11168                    }
11169                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11170                            + " for user " + users[j]);
11171                    broadcastIntentLocked(null, null, intent, null, finisher,
11172                            0, null, null, null, AppOpsManager.OP_NONE,
11173                            true, false, MY_PID, Process.SYSTEM_UID,
11174                            users[j]);
11175                    if (finisher != null) {
11176                        waitingUpdate = true;
11177                    }
11178                }
11179            }
11180        }
11181
11182        return waitingUpdate;
11183    }
11184
11185    public void systemReady(final Runnable goingCallback) {
11186        synchronized(this) {
11187            if (mSystemReady) {
11188                // If we're done calling all the receivers, run the next "boot phase" passed in
11189                // by the SystemServer
11190                if (goingCallback != null) {
11191                    goingCallback.run();
11192                }
11193                return;
11194            }
11195
11196            // Make sure we have the current profile info, since it is needed for
11197            // security checks.
11198            updateCurrentProfileIdsLocked();
11199
11200            if (mRecentTasks == null) {
11201                mRecentTasks = mTaskPersister.restoreTasksLocked();
11202                mTaskPersister.restoreTasksFromOtherDeviceLocked();
11203                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11204                mTaskPersister.startPersisting();
11205            }
11206
11207            // Check to see if there are any update receivers to run.
11208            if (!mDidUpdate) {
11209                if (mWaitingUpdate) {
11210                    return;
11211                }
11212                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11213                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11214                    public void run() {
11215                        synchronized (ActivityManagerService.this) {
11216                            mDidUpdate = true;
11217                        }
11218                        writeLastDonePreBootReceivers(doneReceivers);
11219                        showBootMessage(mContext.getText(R.string.android_upgrading_complete),
11220                                false);
11221                        systemReady(goingCallback);
11222                    }
11223                }, doneReceivers, UserHandle.USER_OWNER);
11224
11225                if (mWaitingUpdate) {
11226                    return;
11227                }
11228                mDidUpdate = true;
11229            }
11230
11231            mAppOpsService.systemReady();
11232            mSystemReady = true;
11233        }
11234
11235        ArrayList<ProcessRecord> procsToKill = null;
11236        synchronized(mPidsSelfLocked) {
11237            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11238                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11239                if (!isAllowedWhileBooting(proc.info)){
11240                    if (procsToKill == null) {
11241                        procsToKill = new ArrayList<ProcessRecord>();
11242                    }
11243                    procsToKill.add(proc);
11244                }
11245            }
11246        }
11247
11248        synchronized(this) {
11249            if (procsToKill != null) {
11250                for (int i=procsToKill.size()-1; i>=0; i--) {
11251                    ProcessRecord proc = procsToKill.get(i);
11252                    Slog.i(TAG, "Removing system update proc: " + proc);
11253                    removeProcessLocked(proc, true, false, "system update done");
11254                }
11255            }
11256
11257            // Now that we have cleaned up any update processes, we
11258            // are ready to start launching real processes and know that
11259            // we won't trample on them any more.
11260            mProcessesReady = true;
11261        }
11262
11263        Slog.i(TAG, "System now ready");
11264        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11265            SystemClock.uptimeMillis());
11266
11267        synchronized(this) {
11268            // Make sure we have no pre-ready processes sitting around.
11269
11270            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11271                ResolveInfo ri = mContext.getPackageManager()
11272                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11273                                STOCK_PM_FLAGS);
11274                CharSequence errorMsg = null;
11275                if (ri != null) {
11276                    ActivityInfo ai = ri.activityInfo;
11277                    ApplicationInfo app = ai.applicationInfo;
11278                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11279                        mTopAction = Intent.ACTION_FACTORY_TEST;
11280                        mTopData = null;
11281                        mTopComponent = new ComponentName(app.packageName,
11282                                ai.name);
11283                    } else {
11284                        errorMsg = mContext.getResources().getText(
11285                                com.android.internal.R.string.factorytest_not_system);
11286                    }
11287                } else {
11288                    errorMsg = mContext.getResources().getText(
11289                            com.android.internal.R.string.factorytest_no_action);
11290                }
11291                if (errorMsg != null) {
11292                    mTopAction = null;
11293                    mTopData = null;
11294                    mTopComponent = null;
11295                    Message msg = Message.obtain();
11296                    msg.what = SHOW_FACTORY_ERROR_MSG;
11297                    msg.getData().putCharSequence("msg", errorMsg);
11298                    mHandler.sendMessage(msg);
11299                }
11300            }
11301        }
11302
11303        retrieveSettings();
11304        loadResourcesOnSystemReady();
11305
11306        synchronized (this) {
11307            readGrantedUriPermissionsLocked();
11308        }
11309
11310        if (goingCallback != null) goingCallback.run();
11311
11312        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11313                Integer.toString(mCurrentUserId), mCurrentUserId);
11314        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11315                Integer.toString(mCurrentUserId), mCurrentUserId);
11316        mSystemServiceManager.startUser(mCurrentUserId);
11317
11318        synchronized (this) {
11319            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11320                try {
11321                    List apps = AppGlobals.getPackageManager().
11322                        getPersistentApplications(STOCK_PM_FLAGS);
11323                    if (apps != null) {
11324                        int N = apps.size();
11325                        int i;
11326                        for (i=0; i<N; i++) {
11327                            ApplicationInfo info
11328                                = (ApplicationInfo)apps.get(i);
11329                            if (info != null &&
11330                                    !info.packageName.equals("android")) {
11331                                addAppLocked(info, false, null /* ABI override */);
11332                            }
11333                        }
11334                    }
11335                } catch (RemoteException ex) {
11336                    // pm is in same process, this will never happen.
11337                }
11338            }
11339
11340            // Start up initial activity.
11341            mBooting = true;
11342            startHomeActivityLocked(mCurrentUserId, "systemReady");
11343
11344            try {
11345                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11346                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11347                            + " data partition or your device will be unstable.");
11348                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11349                }
11350            } catch (RemoteException e) {
11351            }
11352
11353            if (!Build.isFingerprintConsistent()) {
11354                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11355                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11356            }
11357
11358            long ident = Binder.clearCallingIdentity();
11359            try {
11360                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11361                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11362                        | Intent.FLAG_RECEIVER_FOREGROUND);
11363                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11364                broadcastIntentLocked(null, null, intent,
11365                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11366                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11367                intent = new Intent(Intent.ACTION_USER_STARTING);
11368                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11369                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11370                broadcastIntentLocked(null, null, intent,
11371                        null, new IIntentReceiver.Stub() {
11372                            @Override
11373                            public void performReceive(Intent intent, int resultCode, String data,
11374                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11375                                    throws RemoteException {
11376                            }
11377                        }, 0, null, null,
11378                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11379                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11380            } catch (Throwable t) {
11381                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11382            } finally {
11383                Binder.restoreCallingIdentity(ident);
11384            }
11385            mStackSupervisor.resumeTopActivitiesLocked();
11386            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11387        }
11388    }
11389
11390    private boolean makeAppCrashingLocked(ProcessRecord app,
11391            String shortMsg, String longMsg, String stackTrace) {
11392        app.crashing = true;
11393        app.crashingReport = generateProcessError(app,
11394                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11395        startAppProblemLocked(app);
11396        app.stopFreezingAllLocked();
11397        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11398    }
11399
11400    private void makeAppNotRespondingLocked(ProcessRecord app,
11401            String activity, String shortMsg, String longMsg) {
11402        app.notResponding = true;
11403        app.notRespondingReport = generateProcessError(app,
11404                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11405                activity, shortMsg, longMsg, null);
11406        startAppProblemLocked(app);
11407        app.stopFreezingAllLocked();
11408    }
11409
11410    /**
11411     * Generate a process error record, suitable for attachment to a ProcessRecord.
11412     *
11413     * @param app The ProcessRecord in which the error occurred.
11414     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11415     *                      ActivityManager.AppErrorStateInfo
11416     * @param activity The activity associated with the crash, if known.
11417     * @param shortMsg Short message describing the crash.
11418     * @param longMsg Long message describing the crash.
11419     * @param stackTrace Full crash stack trace, may be null.
11420     *
11421     * @return Returns a fully-formed AppErrorStateInfo record.
11422     */
11423    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11424            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11425        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11426
11427        report.condition = condition;
11428        report.processName = app.processName;
11429        report.pid = app.pid;
11430        report.uid = app.info.uid;
11431        report.tag = activity;
11432        report.shortMsg = shortMsg;
11433        report.longMsg = longMsg;
11434        report.stackTrace = stackTrace;
11435
11436        return report;
11437    }
11438
11439    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11440        synchronized (this) {
11441            app.crashing = false;
11442            app.crashingReport = null;
11443            app.notResponding = false;
11444            app.notRespondingReport = null;
11445            if (app.anrDialog == fromDialog) {
11446                app.anrDialog = null;
11447            }
11448            if (app.waitDialog == fromDialog) {
11449                app.waitDialog = null;
11450            }
11451            if (app.pid > 0 && app.pid != MY_PID) {
11452                handleAppCrashLocked(app, null, null, null);
11453                app.kill("user request after error", true);
11454            }
11455        }
11456    }
11457
11458    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11459            String stackTrace) {
11460        long now = SystemClock.uptimeMillis();
11461
11462        Long crashTime;
11463        if (!app.isolated) {
11464            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11465        } else {
11466            crashTime = null;
11467        }
11468        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11469            // This process loses!
11470            Slog.w(TAG, "Process " + app.info.processName
11471                    + " has crashed too many times: killing!");
11472            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11473                    app.userId, app.info.processName, app.uid);
11474            mStackSupervisor.handleAppCrashLocked(app);
11475            if (!app.persistent) {
11476                // We don't want to start this process again until the user
11477                // explicitly does so...  but for persistent process, we really
11478                // need to keep it running.  If a persistent process is actually
11479                // repeatedly crashing, then badness for everyone.
11480                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11481                        app.info.processName);
11482                if (!app.isolated) {
11483                    // XXX We don't have a way to mark isolated processes
11484                    // as bad, since they don't have a peristent identity.
11485                    mBadProcesses.put(app.info.processName, app.uid,
11486                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11487                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11488                }
11489                app.bad = true;
11490                app.removed = true;
11491                // Don't let services in this process be restarted and potentially
11492                // annoy the user repeatedly.  Unless it is persistent, since those
11493                // processes run critical code.
11494                removeProcessLocked(app, false, false, "crash");
11495                mStackSupervisor.resumeTopActivitiesLocked();
11496                return false;
11497            }
11498            mStackSupervisor.resumeTopActivitiesLocked();
11499        } else {
11500            mStackSupervisor.finishTopRunningActivityLocked(app);
11501        }
11502
11503        // Bump up the crash count of any services currently running in the proc.
11504        for (int i=app.services.size()-1; i>=0; i--) {
11505            // Any services running in the application need to be placed
11506            // back in the pending list.
11507            ServiceRecord sr = app.services.valueAt(i);
11508            sr.crashCount++;
11509        }
11510
11511        // If the crashing process is what we consider to be the "home process" and it has been
11512        // replaced by a third-party app, clear the package preferred activities from packages
11513        // with a home activity running in the process to prevent a repeatedly crashing app
11514        // from blocking the user to manually clear the list.
11515        final ArrayList<ActivityRecord> activities = app.activities;
11516        if (app == mHomeProcess && activities.size() > 0
11517                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11518            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11519                final ActivityRecord r = activities.get(activityNdx);
11520                if (r.isHomeActivity()) {
11521                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11522                    try {
11523                        ActivityThread.getPackageManager()
11524                                .clearPackagePreferredActivities(r.packageName);
11525                    } catch (RemoteException c) {
11526                        // pm is in same process, this will never happen.
11527                    }
11528                }
11529            }
11530        }
11531
11532        if (!app.isolated) {
11533            // XXX Can't keep track of crash times for isolated processes,
11534            // because they don't have a perisistent identity.
11535            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11536        }
11537
11538        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11539        return true;
11540    }
11541
11542    void startAppProblemLocked(ProcessRecord app) {
11543        // If this app is not running under the current user, then we
11544        // can't give it a report button because that would require
11545        // launching the report UI under a different user.
11546        app.errorReportReceiver = null;
11547
11548        for (int userId : mCurrentProfileIds) {
11549            if (app.userId == userId) {
11550                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11551                        mContext, app.info.packageName, app.info.flags);
11552            }
11553        }
11554        skipCurrentReceiverLocked(app);
11555    }
11556
11557    void skipCurrentReceiverLocked(ProcessRecord app) {
11558        for (BroadcastQueue queue : mBroadcastQueues) {
11559            queue.skipCurrentReceiverLocked(app);
11560        }
11561    }
11562
11563    /**
11564     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11565     * The application process will exit immediately after this call returns.
11566     * @param app object of the crashing app, null for the system server
11567     * @param crashInfo describing the exception
11568     */
11569    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11570        ProcessRecord r = findAppProcess(app, "Crash");
11571        final String processName = app == null ? "system_server"
11572                : (r == null ? "unknown" : r.processName);
11573
11574        handleApplicationCrashInner("crash", r, processName, crashInfo);
11575    }
11576
11577    /* Native crash reporting uses this inner version because it needs to be somewhat
11578     * decoupled from the AM-managed cleanup lifecycle
11579     */
11580    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11581            ApplicationErrorReport.CrashInfo crashInfo) {
11582        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11583                UserHandle.getUserId(Binder.getCallingUid()), processName,
11584                r == null ? -1 : r.info.flags,
11585                crashInfo.exceptionClassName,
11586                crashInfo.exceptionMessage,
11587                crashInfo.throwFileName,
11588                crashInfo.throwLineNumber);
11589
11590        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11591
11592        crashApplication(r, crashInfo);
11593    }
11594
11595    public void handleApplicationStrictModeViolation(
11596            IBinder app,
11597            int violationMask,
11598            StrictMode.ViolationInfo info) {
11599        ProcessRecord r = findAppProcess(app, "StrictMode");
11600        if (r == null) {
11601            return;
11602        }
11603
11604        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11605            Integer stackFingerprint = info.hashCode();
11606            boolean logIt = true;
11607            synchronized (mAlreadyLoggedViolatedStacks) {
11608                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11609                    logIt = false;
11610                    // TODO: sub-sample into EventLog for these, with
11611                    // the info.durationMillis?  Then we'd get
11612                    // the relative pain numbers, without logging all
11613                    // the stack traces repeatedly.  We'd want to do
11614                    // likewise in the client code, which also does
11615                    // dup suppression, before the Binder call.
11616                } else {
11617                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11618                        mAlreadyLoggedViolatedStacks.clear();
11619                    }
11620                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11621                }
11622            }
11623            if (logIt) {
11624                logStrictModeViolationToDropBox(r, info);
11625            }
11626        }
11627
11628        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11629            AppErrorResult result = new AppErrorResult();
11630            synchronized (this) {
11631                final long origId = Binder.clearCallingIdentity();
11632
11633                Message msg = Message.obtain();
11634                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11635                HashMap<String, Object> data = new HashMap<String, Object>();
11636                data.put("result", result);
11637                data.put("app", r);
11638                data.put("violationMask", violationMask);
11639                data.put("info", info);
11640                msg.obj = data;
11641                mHandler.sendMessage(msg);
11642
11643                Binder.restoreCallingIdentity(origId);
11644            }
11645            int res = result.get();
11646            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11647        }
11648    }
11649
11650    // Depending on the policy in effect, there could be a bunch of
11651    // these in quick succession so we try to batch these together to
11652    // minimize disk writes, number of dropbox entries, and maximize
11653    // compression, by having more fewer, larger records.
11654    private void logStrictModeViolationToDropBox(
11655            ProcessRecord process,
11656            StrictMode.ViolationInfo info) {
11657        if (info == null) {
11658            return;
11659        }
11660        final boolean isSystemApp = process == null ||
11661                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11662                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11663        final String processName = process == null ? "unknown" : process.processName;
11664        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11665        final DropBoxManager dbox = (DropBoxManager)
11666                mContext.getSystemService(Context.DROPBOX_SERVICE);
11667
11668        // Exit early if the dropbox isn't configured to accept this report type.
11669        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11670
11671        boolean bufferWasEmpty;
11672        boolean needsFlush;
11673        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11674        synchronized (sb) {
11675            bufferWasEmpty = sb.length() == 0;
11676            appendDropBoxProcessHeaders(process, processName, sb);
11677            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11678            sb.append("System-App: ").append(isSystemApp).append("\n");
11679            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11680            if (info.violationNumThisLoop != 0) {
11681                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11682            }
11683            if (info.numAnimationsRunning != 0) {
11684                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11685            }
11686            if (info.broadcastIntentAction != null) {
11687                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11688            }
11689            if (info.durationMillis != -1) {
11690                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11691            }
11692            if (info.numInstances != -1) {
11693                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11694            }
11695            if (info.tags != null) {
11696                for (String tag : info.tags) {
11697                    sb.append("Span-Tag: ").append(tag).append("\n");
11698                }
11699            }
11700            sb.append("\n");
11701            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11702                sb.append(info.crashInfo.stackTrace);
11703            }
11704            sb.append("\n");
11705
11706            // Only buffer up to ~64k.  Various logging bits truncate
11707            // things at 128k.
11708            needsFlush = (sb.length() > 64 * 1024);
11709        }
11710
11711        // Flush immediately if the buffer's grown too large, or this
11712        // is a non-system app.  Non-system apps are isolated with a
11713        // different tag & policy and not batched.
11714        //
11715        // Batching is useful during internal testing with
11716        // StrictMode settings turned up high.  Without batching,
11717        // thousands of separate files could be created on boot.
11718        if (!isSystemApp || needsFlush) {
11719            new Thread("Error dump: " + dropboxTag) {
11720                @Override
11721                public void run() {
11722                    String report;
11723                    synchronized (sb) {
11724                        report = sb.toString();
11725                        sb.delete(0, sb.length());
11726                        sb.trimToSize();
11727                    }
11728                    if (report.length() != 0) {
11729                        dbox.addText(dropboxTag, report);
11730                    }
11731                }
11732            }.start();
11733            return;
11734        }
11735
11736        // System app batching:
11737        if (!bufferWasEmpty) {
11738            // An existing dropbox-writing thread is outstanding, so
11739            // we don't need to start it up.  The existing thread will
11740            // catch the buffer appends we just did.
11741            return;
11742        }
11743
11744        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11745        // (After this point, we shouldn't access AMS internal data structures.)
11746        new Thread("Error dump: " + dropboxTag) {
11747            @Override
11748            public void run() {
11749                // 5 second sleep to let stacks arrive and be batched together
11750                try {
11751                    Thread.sleep(5000);  // 5 seconds
11752                } catch (InterruptedException e) {}
11753
11754                String errorReport;
11755                synchronized (mStrictModeBuffer) {
11756                    errorReport = mStrictModeBuffer.toString();
11757                    if (errorReport.length() == 0) {
11758                        return;
11759                    }
11760                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11761                    mStrictModeBuffer.trimToSize();
11762                }
11763                dbox.addText(dropboxTag, errorReport);
11764            }
11765        }.start();
11766    }
11767
11768    /**
11769     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11770     * @param app object of the crashing app, null for the system server
11771     * @param tag reported by the caller
11772     * @param system whether this wtf is coming from the system
11773     * @param crashInfo describing the context of the error
11774     * @return true if the process should exit immediately (WTF is fatal)
11775     */
11776    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11777            final ApplicationErrorReport.CrashInfo crashInfo) {
11778        final int callingUid = Binder.getCallingUid();
11779        final int callingPid = Binder.getCallingPid();
11780
11781        if (system) {
11782            // If this is coming from the system, we could very well have low-level
11783            // system locks held, so we want to do this all asynchronously.  And we
11784            // never want this to become fatal, so there is that too.
11785            mHandler.post(new Runnable() {
11786                @Override public void run() {
11787                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11788                }
11789            });
11790            return false;
11791        }
11792
11793        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11794                crashInfo);
11795
11796        if (r != null && r.pid != Process.myPid() &&
11797                Settings.Global.getInt(mContext.getContentResolver(),
11798                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11799            crashApplication(r, crashInfo);
11800            return true;
11801        } else {
11802            return false;
11803        }
11804    }
11805
11806    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11807            final ApplicationErrorReport.CrashInfo crashInfo) {
11808        final ProcessRecord r = findAppProcess(app, "WTF");
11809        final String processName = app == null ? "system_server"
11810                : (r == null ? "unknown" : r.processName);
11811
11812        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11813                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11814
11815        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11816
11817        return r;
11818    }
11819
11820    /**
11821     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11822     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11823     */
11824    private ProcessRecord findAppProcess(IBinder app, String reason) {
11825        if (app == null) {
11826            return null;
11827        }
11828
11829        synchronized (this) {
11830            final int NP = mProcessNames.getMap().size();
11831            for (int ip=0; ip<NP; ip++) {
11832                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11833                final int NA = apps.size();
11834                for (int ia=0; ia<NA; ia++) {
11835                    ProcessRecord p = apps.valueAt(ia);
11836                    if (p.thread != null && p.thread.asBinder() == app) {
11837                        return p;
11838                    }
11839                }
11840            }
11841
11842            Slog.w(TAG, "Can't find mystery application for " + reason
11843                    + " from pid=" + Binder.getCallingPid()
11844                    + " uid=" + Binder.getCallingUid() + ": " + app);
11845            return null;
11846        }
11847    }
11848
11849    /**
11850     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11851     * to append various headers to the dropbox log text.
11852     */
11853    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11854            StringBuilder sb) {
11855        // Watchdog thread ends up invoking this function (with
11856        // a null ProcessRecord) to add the stack file to dropbox.
11857        // Do not acquire a lock on this (am) in such cases, as it
11858        // could cause a potential deadlock, if and when watchdog
11859        // is invoked due to unavailability of lock on am and it
11860        // would prevent watchdog from killing system_server.
11861        if (process == null) {
11862            sb.append("Process: ").append(processName).append("\n");
11863            return;
11864        }
11865        // Note: ProcessRecord 'process' is guarded by the service
11866        // instance.  (notably process.pkgList, which could otherwise change
11867        // concurrently during execution of this method)
11868        synchronized (this) {
11869            sb.append("Process: ").append(processName).append("\n");
11870            int flags = process.info.flags;
11871            IPackageManager pm = AppGlobals.getPackageManager();
11872            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11873            for (int ip=0; ip<process.pkgList.size(); ip++) {
11874                String pkg = process.pkgList.keyAt(ip);
11875                sb.append("Package: ").append(pkg);
11876                try {
11877                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11878                    if (pi != null) {
11879                        sb.append(" v").append(pi.versionCode);
11880                        if (pi.versionName != null) {
11881                            sb.append(" (").append(pi.versionName).append(")");
11882                        }
11883                    }
11884                } catch (RemoteException e) {
11885                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11886                }
11887                sb.append("\n");
11888            }
11889        }
11890    }
11891
11892    private static String processClass(ProcessRecord process) {
11893        if (process == null || process.pid == MY_PID) {
11894            return "system_server";
11895        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11896            return "system_app";
11897        } else {
11898            return "data_app";
11899        }
11900    }
11901
11902    /**
11903     * Write a description of an error (crash, WTF, ANR) to the drop box.
11904     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11905     * @param process which caused the error, null means the system server
11906     * @param activity which triggered the error, null if unknown
11907     * @param parent activity related to the error, null if unknown
11908     * @param subject line related to the error, null if absent
11909     * @param report in long form describing the error, null if absent
11910     * @param logFile to include in the report, null if none
11911     * @param crashInfo giving an application stack trace, null if absent
11912     */
11913    public void addErrorToDropBox(String eventType,
11914            ProcessRecord process, String processName, ActivityRecord activity,
11915            ActivityRecord parent, String subject,
11916            final String report, final File logFile,
11917            final ApplicationErrorReport.CrashInfo crashInfo) {
11918        // NOTE -- this must never acquire the ActivityManagerService lock,
11919        // otherwise the watchdog may be prevented from resetting the system.
11920
11921        final String dropboxTag = processClass(process) + "_" + eventType;
11922        final DropBoxManager dbox = (DropBoxManager)
11923                mContext.getSystemService(Context.DROPBOX_SERVICE);
11924
11925        // Exit early if the dropbox isn't configured to accept this report type.
11926        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11927
11928        final StringBuilder sb = new StringBuilder(1024);
11929        appendDropBoxProcessHeaders(process, processName, sb);
11930        if (activity != null) {
11931            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11932        }
11933        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11934            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11935        }
11936        if (parent != null && parent != activity) {
11937            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11938        }
11939        if (subject != null) {
11940            sb.append("Subject: ").append(subject).append("\n");
11941        }
11942        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11943        if (Debug.isDebuggerConnected()) {
11944            sb.append("Debugger: Connected\n");
11945        }
11946        sb.append("\n");
11947
11948        // Do the rest in a worker thread to avoid blocking the caller on I/O
11949        // (After this point, we shouldn't access AMS internal data structures.)
11950        Thread worker = new Thread("Error dump: " + dropboxTag) {
11951            @Override
11952            public void run() {
11953                if (report != null) {
11954                    sb.append(report);
11955                }
11956                if (logFile != null) {
11957                    try {
11958                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11959                                    "\n\n[[TRUNCATED]]"));
11960                    } catch (IOException e) {
11961                        Slog.e(TAG, "Error reading " + logFile, e);
11962                    }
11963                }
11964                if (crashInfo != null && crashInfo.stackTrace != null) {
11965                    sb.append(crashInfo.stackTrace);
11966                }
11967
11968                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11969                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11970                if (lines > 0) {
11971                    sb.append("\n");
11972
11973                    // Merge several logcat streams, and take the last N lines
11974                    InputStreamReader input = null;
11975                    try {
11976                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11977                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11978                                "-b", "crash",
11979                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11980
11981                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11982                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11983                        input = new InputStreamReader(logcat.getInputStream());
11984
11985                        int num;
11986                        char[] buf = new char[8192];
11987                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11988                    } catch (IOException e) {
11989                        Slog.e(TAG, "Error running logcat", e);
11990                    } finally {
11991                        if (input != null) try { input.close(); } catch (IOException e) {}
11992                    }
11993                }
11994
11995                dbox.addText(dropboxTag, sb.toString());
11996            }
11997        };
11998
11999        if (process == null) {
12000            // If process is null, we are being called from some internal code
12001            // and may be about to die -- run this synchronously.
12002            worker.run();
12003        } else {
12004            worker.start();
12005        }
12006    }
12007
12008    /**
12009     * Bring up the "unexpected error" dialog box for a crashing app.
12010     * Deal with edge cases (intercepts from instrumented applications,
12011     * ActivityController, error intent receivers, that sort of thing).
12012     * @param r the application crashing
12013     * @param crashInfo describing the failure
12014     */
12015    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12016        long timeMillis = System.currentTimeMillis();
12017        String shortMsg = crashInfo.exceptionClassName;
12018        String longMsg = crashInfo.exceptionMessage;
12019        String stackTrace = crashInfo.stackTrace;
12020        if (shortMsg != null && longMsg != null) {
12021            longMsg = shortMsg + ": " + longMsg;
12022        } else if (shortMsg != null) {
12023            longMsg = shortMsg;
12024        }
12025
12026        AppErrorResult result = new AppErrorResult();
12027        synchronized (this) {
12028            if (mController != null) {
12029                try {
12030                    String name = r != null ? r.processName : null;
12031                    int pid = r != null ? r.pid : Binder.getCallingPid();
12032                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12033                    if (!mController.appCrashed(name, pid,
12034                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12035                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12036                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12037                            Slog.w(TAG, "Skip killing native crashed app " + name
12038                                    + "(" + pid + ") during testing");
12039                        } else {
12040                            Slog.w(TAG, "Force-killing crashed app " + name
12041                                    + " at watcher's request");
12042                            if (r != null) {
12043                                r.kill("crash", true);
12044                            } else {
12045                                // Huh.
12046                                Process.killProcess(pid);
12047                                Process.killProcessGroup(uid, pid);
12048                            }
12049                        }
12050                        return;
12051                    }
12052                } catch (RemoteException e) {
12053                    mController = null;
12054                    Watchdog.getInstance().setActivityController(null);
12055                }
12056            }
12057
12058            final long origId = Binder.clearCallingIdentity();
12059
12060            // If this process is running instrumentation, finish it.
12061            if (r != null && r.instrumentationClass != null) {
12062                Slog.w(TAG, "Error in app " + r.processName
12063                      + " running instrumentation " + r.instrumentationClass + ":");
12064                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12065                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12066                Bundle info = new Bundle();
12067                info.putString("shortMsg", shortMsg);
12068                info.putString("longMsg", longMsg);
12069                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12070                Binder.restoreCallingIdentity(origId);
12071                return;
12072            }
12073
12074            // Log crash in battery stats.
12075            if (r != null) {
12076                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12077            }
12078
12079            // If we can't identify the process or it's already exceeded its crash quota,
12080            // quit right away without showing a crash dialog.
12081            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12082                Binder.restoreCallingIdentity(origId);
12083                return;
12084            }
12085
12086            Message msg = Message.obtain();
12087            msg.what = SHOW_ERROR_MSG;
12088            HashMap data = new HashMap();
12089            data.put("result", result);
12090            data.put("app", r);
12091            msg.obj = data;
12092            mHandler.sendMessage(msg);
12093
12094            Binder.restoreCallingIdentity(origId);
12095        }
12096
12097        int res = result.get();
12098
12099        Intent appErrorIntent = null;
12100        synchronized (this) {
12101            if (r != null && !r.isolated) {
12102                // XXX Can't keep track of crash time for isolated processes,
12103                // since they don't have a persistent identity.
12104                mProcessCrashTimes.put(r.info.processName, r.uid,
12105                        SystemClock.uptimeMillis());
12106            }
12107            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12108                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12109            }
12110        }
12111
12112        if (appErrorIntent != null) {
12113            try {
12114                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12115            } catch (ActivityNotFoundException e) {
12116                Slog.w(TAG, "bug report receiver dissappeared", e);
12117            }
12118        }
12119    }
12120
12121    Intent createAppErrorIntentLocked(ProcessRecord r,
12122            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12123        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12124        if (report == null) {
12125            return null;
12126        }
12127        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12128        result.setComponent(r.errorReportReceiver);
12129        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12130        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12131        return result;
12132    }
12133
12134    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12135            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12136        if (r.errorReportReceiver == null) {
12137            return null;
12138        }
12139
12140        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12141            return null;
12142        }
12143
12144        ApplicationErrorReport report = new ApplicationErrorReport();
12145        report.packageName = r.info.packageName;
12146        report.installerPackageName = r.errorReportReceiver.getPackageName();
12147        report.processName = r.processName;
12148        report.time = timeMillis;
12149        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12150
12151        if (r.crashing || r.forceCrashReport) {
12152            report.type = ApplicationErrorReport.TYPE_CRASH;
12153            report.crashInfo = crashInfo;
12154        } else if (r.notResponding) {
12155            report.type = ApplicationErrorReport.TYPE_ANR;
12156            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12157
12158            report.anrInfo.activity = r.notRespondingReport.tag;
12159            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12160            report.anrInfo.info = r.notRespondingReport.longMsg;
12161        }
12162
12163        return report;
12164    }
12165
12166    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12167        enforceNotIsolatedCaller("getProcessesInErrorState");
12168        // assume our apps are happy - lazy create the list
12169        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12170
12171        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12172                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12173        int userId = UserHandle.getUserId(Binder.getCallingUid());
12174
12175        synchronized (this) {
12176
12177            // iterate across all processes
12178            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12179                ProcessRecord app = mLruProcesses.get(i);
12180                if (!allUsers && app.userId != userId) {
12181                    continue;
12182                }
12183                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12184                    // This one's in trouble, so we'll generate a report for it
12185                    // crashes are higher priority (in case there's a crash *and* an anr)
12186                    ActivityManager.ProcessErrorStateInfo report = null;
12187                    if (app.crashing) {
12188                        report = app.crashingReport;
12189                    } else if (app.notResponding) {
12190                        report = app.notRespondingReport;
12191                    }
12192
12193                    if (report != null) {
12194                        if (errList == null) {
12195                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12196                        }
12197                        errList.add(report);
12198                    } else {
12199                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12200                                " crashing = " + app.crashing +
12201                                " notResponding = " + app.notResponding);
12202                    }
12203                }
12204            }
12205        }
12206
12207        return errList;
12208    }
12209
12210    static int procStateToImportance(int procState, int memAdj,
12211            ActivityManager.RunningAppProcessInfo currApp) {
12212        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12213        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12214            currApp.lru = memAdj;
12215        } else {
12216            currApp.lru = 0;
12217        }
12218        return imp;
12219    }
12220
12221    private void fillInProcMemInfo(ProcessRecord app,
12222            ActivityManager.RunningAppProcessInfo outInfo) {
12223        outInfo.pid = app.pid;
12224        outInfo.uid = app.info.uid;
12225        if (mHeavyWeightProcess == app) {
12226            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12227        }
12228        if (app.persistent) {
12229            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12230        }
12231        if (app.activities.size() > 0) {
12232            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12233        }
12234        outInfo.lastTrimLevel = app.trimMemoryLevel;
12235        int adj = app.curAdj;
12236        int procState = app.curProcState;
12237        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12238        outInfo.importanceReasonCode = app.adjTypeCode;
12239        outInfo.processState = app.curProcState;
12240    }
12241
12242    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12243        enforceNotIsolatedCaller("getRunningAppProcesses");
12244        // Lazy instantiation of list
12245        List<ActivityManager.RunningAppProcessInfo> runList = null;
12246        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12247                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12248        int userId = UserHandle.getUserId(Binder.getCallingUid());
12249        synchronized (this) {
12250            // Iterate across all processes
12251            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12252                ProcessRecord app = mLruProcesses.get(i);
12253                if (!allUsers && app.userId != userId) {
12254                    continue;
12255                }
12256                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12257                    // Generate process state info for running application
12258                    ActivityManager.RunningAppProcessInfo currApp =
12259                        new ActivityManager.RunningAppProcessInfo(app.processName,
12260                                app.pid, app.getPackageList());
12261                    fillInProcMemInfo(app, currApp);
12262                    if (app.adjSource instanceof ProcessRecord) {
12263                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12264                        currApp.importanceReasonImportance =
12265                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12266                                        app.adjSourceProcState);
12267                    } else if (app.adjSource instanceof ActivityRecord) {
12268                        ActivityRecord r = (ActivityRecord)app.adjSource;
12269                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12270                    }
12271                    if (app.adjTarget instanceof ComponentName) {
12272                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12273                    }
12274                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12275                    //        + " lru=" + currApp.lru);
12276                    if (runList == null) {
12277                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12278                    }
12279                    runList.add(currApp);
12280                }
12281            }
12282        }
12283        return runList;
12284    }
12285
12286    public List<ApplicationInfo> getRunningExternalApplications() {
12287        enforceNotIsolatedCaller("getRunningExternalApplications");
12288        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12289        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12290        if (runningApps != null && runningApps.size() > 0) {
12291            Set<String> extList = new HashSet<String>();
12292            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12293                if (app.pkgList != null) {
12294                    for (String pkg : app.pkgList) {
12295                        extList.add(pkg);
12296                    }
12297                }
12298            }
12299            IPackageManager pm = AppGlobals.getPackageManager();
12300            for (String pkg : extList) {
12301                try {
12302                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12303                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12304                        retList.add(info);
12305                    }
12306                } catch (RemoteException e) {
12307                }
12308            }
12309        }
12310        return retList;
12311    }
12312
12313    @Override
12314    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12315        enforceNotIsolatedCaller("getMyMemoryState");
12316        synchronized (this) {
12317            ProcessRecord proc;
12318            synchronized (mPidsSelfLocked) {
12319                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12320            }
12321            fillInProcMemInfo(proc, outInfo);
12322        }
12323    }
12324
12325    @Override
12326    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12327        if (checkCallingPermission(android.Manifest.permission.DUMP)
12328                != PackageManager.PERMISSION_GRANTED) {
12329            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12330                    + Binder.getCallingPid()
12331                    + ", uid=" + Binder.getCallingUid()
12332                    + " without permission "
12333                    + android.Manifest.permission.DUMP);
12334            return;
12335        }
12336
12337        boolean dumpAll = false;
12338        boolean dumpClient = false;
12339        String dumpPackage = null;
12340
12341        int opti = 0;
12342        while (opti < args.length) {
12343            String opt = args[opti];
12344            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12345                break;
12346            }
12347            opti++;
12348            if ("-a".equals(opt)) {
12349                dumpAll = true;
12350            } else if ("-c".equals(opt)) {
12351                dumpClient = true;
12352            } else if ("-p".equals(opt)) {
12353                if (opti < args.length) {
12354                    dumpPackage = args[opti];
12355                    opti++;
12356                } else {
12357                    pw.println("Error: -p option requires package argument");
12358                    return;
12359                }
12360                dumpClient = true;
12361            } else if ("-h".equals(opt)) {
12362                pw.println("Activity manager dump options:");
12363                pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12364                pw.println("  cmd may be one of:");
12365                pw.println("    a[ctivities]: activity stack state");
12366                pw.println("    r[recents]: recent activities state");
12367                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12368                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12369                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12370                pw.println("    o[om]: out of memory management");
12371                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12372                pw.println("    provider [COMP_SPEC]: provider client-side state");
12373                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12374                pw.println("    as[sociations]: tracked app associations");
12375                pw.println("    service [COMP_SPEC]: service client-side state");
12376                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12377                pw.println("    all: dump all activities");
12378                pw.println("    top: dump the top activity");
12379                pw.println("    write: write all pending state to storage");
12380                pw.println("    track-associations: enable association tracking");
12381                pw.println("    untrack-associations: disable and clear association tracking");
12382                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12383                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12384                pw.println("    a partial substring in a component name, a");
12385                pw.println("    hex object identifier.");
12386                pw.println("  -a: include all available server state.");
12387                pw.println("  -c: include client state.");
12388                pw.println("  -p: limit output to given package.");
12389                return;
12390            } else {
12391                pw.println("Unknown argument: " + opt + "; use -h for help");
12392            }
12393        }
12394
12395        long origId = Binder.clearCallingIdentity();
12396        boolean more = false;
12397        // Is the caller requesting to dump a particular piece of data?
12398        if (opti < args.length) {
12399            String cmd = args[opti];
12400            opti++;
12401            if ("activities".equals(cmd) || "a".equals(cmd)) {
12402                synchronized (this) {
12403                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12404                }
12405            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12406                synchronized (this) {
12407                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12408                }
12409            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12410                String[] newArgs;
12411                String name;
12412                if (opti >= args.length) {
12413                    name = null;
12414                    newArgs = EMPTY_STRING_ARRAY;
12415                } else {
12416                    dumpPackage = args[opti];
12417                    opti++;
12418                    newArgs = new String[args.length - opti];
12419                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12420                            args.length - opti);
12421                }
12422                synchronized (this) {
12423                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12424                }
12425            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12426                String[] newArgs;
12427                String name;
12428                if (opti >= args.length) {
12429                    name = null;
12430                    newArgs = EMPTY_STRING_ARRAY;
12431                } else {
12432                    dumpPackage = args[opti];
12433                    opti++;
12434                    newArgs = new String[args.length - opti];
12435                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12436                            args.length - opti);
12437                }
12438                synchronized (this) {
12439                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12440                }
12441            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12442                String[] newArgs;
12443                String name;
12444                if (opti >= args.length) {
12445                    name = null;
12446                    newArgs = EMPTY_STRING_ARRAY;
12447                } else {
12448                    dumpPackage = args[opti];
12449                    opti++;
12450                    newArgs = new String[args.length - opti];
12451                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12452                            args.length - opti);
12453                }
12454                synchronized (this) {
12455                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12456                }
12457            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12458                synchronized (this) {
12459                    dumpOomLocked(fd, pw, args, opti, true);
12460                }
12461            } else if ("provider".equals(cmd)) {
12462                String[] newArgs;
12463                String name;
12464                if (opti >= args.length) {
12465                    name = null;
12466                    newArgs = EMPTY_STRING_ARRAY;
12467                } else {
12468                    name = args[opti];
12469                    opti++;
12470                    newArgs = new String[args.length - opti];
12471                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12472                }
12473                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12474                    pw.println("No providers match: " + name);
12475                    pw.println("Use -h for help.");
12476                }
12477            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12478                synchronized (this) {
12479                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12480                }
12481            } else if ("service".equals(cmd)) {
12482                String[] newArgs;
12483                String name;
12484                if (opti >= args.length) {
12485                    name = null;
12486                    newArgs = EMPTY_STRING_ARRAY;
12487                } else {
12488                    name = args[opti];
12489                    opti++;
12490                    newArgs = new String[args.length - opti];
12491                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12492                            args.length - opti);
12493                }
12494                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12495                    pw.println("No services match: " + name);
12496                    pw.println("Use -h for help.");
12497                }
12498            } else if ("package".equals(cmd)) {
12499                String[] newArgs;
12500                if (opti >= args.length) {
12501                    pw.println("package: no package name specified");
12502                    pw.println("Use -h for help.");
12503                } else {
12504                    dumpPackage = args[opti];
12505                    opti++;
12506                    newArgs = new String[args.length - opti];
12507                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12508                            args.length - opti);
12509                    args = newArgs;
12510                    opti = 0;
12511                    more = true;
12512                }
12513            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12514                synchronized (this) {
12515                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12516                }
12517            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12518                synchronized (this) {
12519                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12520                }
12521            } else if ("write".equals(cmd)) {
12522                mTaskPersister.flush();
12523                pw.println("All tasks persisted.");
12524                return;
12525            } else if ("track-associations".equals(cmd)) {
12526                synchronized (this) {
12527                    if (!mTrackingAssociations) {
12528                        mTrackingAssociations = true;
12529                        pw.println("Association tracking started.");
12530                    } else {
12531                        pw.println("Association tracking already enabled.");
12532                    }
12533                }
12534                return;
12535            } else if ("untrack-associations".equals(cmd)) {
12536                synchronized (this) {
12537                    if (mTrackingAssociations) {
12538                        mTrackingAssociations = false;
12539                        mAssociations.clear();
12540                        pw.println("Association tracking stopped.");
12541                    } else {
12542                        pw.println("Association tracking not running.");
12543                    }
12544                }
12545                return;
12546            } else {
12547                // Dumping a single activity?
12548                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12549                    pw.println("Bad activity command, or no activities match: " + cmd);
12550                    pw.println("Use -h for help.");
12551                }
12552            }
12553            if (!more) {
12554                Binder.restoreCallingIdentity(origId);
12555                return;
12556            }
12557        }
12558
12559        // No piece of data specified, dump everything.
12560        synchronized (this) {
12561            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12562            pw.println();
12563            if (dumpAll) {
12564                pw.println("-------------------------------------------------------------------------------");
12565            }
12566            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12567            pw.println();
12568            if (dumpAll) {
12569                pw.println("-------------------------------------------------------------------------------");
12570            }
12571            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12572            pw.println();
12573            if (dumpAll) {
12574                pw.println("-------------------------------------------------------------------------------");
12575            }
12576            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12577            pw.println();
12578            if (dumpAll) {
12579                pw.println("-------------------------------------------------------------------------------");
12580            }
12581            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12582            pw.println();
12583            if (dumpAll) {
12584                pw.println("-------------------------------------------------------------------------------");
12585            }
12586            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12587            if (mAssociations.size() > 0) {
12588                pw.println();
12589                if (dumpAll) {
12590                    pw.println("-------------------------------------------------------------------------------");
12591                }
12592                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12593            }
12594            pw.println();
12595            if (dumpAll) {
12596                pw.println("-------------------------------------------------------------------------------");
12597            }
12598            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12599        }
12600        Binder.restoreCallingIdentity(origId);
12601    }
12602
12603    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12604            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12605        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12606
12607        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12608                dumpPackage);
12609        boolean needSep = printedAnything;
12610
12611        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12612                dumpPackage, needSep, "  mFocusedActivity: ");
12613        if (printed) {
12614            printedAnything = true;
12615            needSep = false;
12616        }
12617
12618        if (dumpPackage == null) {
12619            if (needSep) {
12620                pw.println();
12621            }
12622            needSep = true;
12623            printedAnything = true;
12624            mStackSupervisor.dump(pw, "  ");
12625        }
12626
12627        if (!printedAnything) {
12628            pw.println("  (nothing)");
12629        }
12630    }
12631
12632    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12633            int opti, boolean dumpAll, String dumpPackage) {
12634        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12635
12636        boolean printedAnything = false;
12637
12638        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12639            boolean printedHeader = false;
12640
12641            final int N = mRecentTasks.size();
12642            for (int i=0; i<N; i++) {
12643                TaskRecord tr = mRecentTasks.get(i);
12644                if (dumpPackage != null) {
12645                    if (tr.realActivity == null ||
12646                            !dumpPackage.equals(tr.realActivity)) {
12647                        continue;
12648                    }
12649                }
12650                if (!printedHeader) {
12651                    pw.println("  Recent tasks:");
12652                    printedHeader = true;
12653                    printedAnything = true;
12654                }
12655                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12656                        pw.println(tr);
12657                if (dumpAll) {
12658                    mRecentTasks.get(i).dump(pw, "    ");
12659                }
12660            }
12661        }
12662
12663        if (!printedAnything) {
12664            pw.println("  (nothing)");
12665        }
12666    }
12667
12668    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12669            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12670        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12671
12672        int dumpUid = 0;
12673        if (dumpPackage != null) {
12674            IPackageManager pm = AppGlobals.getPackageManager();
12675            try {
12676                dumpUid = pm.getPackageUid(dumpPackage, 0);
12677            } catch (RemoteException e) {
12678            }
12679        }
12680
12681        boolean printedAnything = false;
12682
12683        final long now = SystemClock.uptimeMillis();
12684
12685        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12686            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12687                    = mAssociations.valueAt(i1);
12688            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12689                SparseArray<ArrayMap<String, Association>> sourceUids
12690                        = targetComponents.valueAt(i2);
12691                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12692                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12693                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12694                        Association ass = sourceProcesses.valueAt(i4);
12695                        if (dumpPackage != null) {
12696                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12697                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12698                                continue;
12699                            }
12700                        }
12701                        printedAnything = true;
12702                        pw.print("  ");
12703                        pw.print(ass.mTargetProcess);
12704                        pw.print("/");
12705                        UserHandle.formatUid(pw, ass.mTargetUid);
12706                        pw.print(" <- ");
12707                        pw.print(ass.mSourceProcess);
12708                        pw.print("/");
12709                        UserHandle.formatUid(pw, ass.mSourceUid);
12710                        pw.println();
12711                        pw.print("    via ");
12712                        pw.print(ass.mTargetComponent.flattenToShortString());
12713                        pw.println();
12714                        pw.print("    ");
12715                        long dur = ass.mTime;
12716                        if (ass.mNesting > 0) {
12717                            dur += now - ass.mStartTime;
12718                        }
12719                        TimeUtils.formatDuration(dur, pw);
12720                        pw.print(" (");
12721                        pw.print(ass.mCount);
12722                        pw.println(" times)");
12723                        if (ass.mNesting > 0) {
12724                            pw.print("    ");
12725                            pw.print(" Currently active: ");
12726                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
12727                            pw.println();
12728                        }
12729                    }
12730                }
12731            }
12732
12733        }
12734
12735        if (!printedAnything) {
12736            pw.println("  (nothing)");
12737        }
12738    }
12739
12740    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12741            int opti, boolean dumpAll, String dumpPackage) {
12742        boolean needSep = false;
12743        boolean printedAnything = false;
12744        int numPers = 0;
12745
12746        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12747
12748        if (dumpAll) {
12749            final int NP = mProcessNames.getMap().size();
12750            for (int ip=0; ip<NP; ip++) {
12751                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12752                final int NA = procs.size();
12753                for (int ia=0; ia<NA; ia++) {
12754                    ProcessRecord r = procs.valueAt(ia);
12755                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12756                        continue;
12757                    }
12758                    if (!needSep) {
12759                        pw.println("  All known processes:");
12760                        needSep = true;
12761                        printedAnything = true;
12762                    }
12763                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12764                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12765                        pw.print(" "); pw.println(r);
12766                    r.dump(pw, "    ");
12767                    if (r.persistent) {
12768                        numPers++;
12769                    }
12770                }
12771            }
12772        }
12773
12774        if (mIsolatedProcesses.size() > 0) {
12775            boolean printed = false;
12776            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12777                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12778                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12779                    continue;
12780                }
12781                if (!printed) {
12782                    if (needSep) {
12783                        pw.println();
12784                    }
12785                    pw.println("  Isolated process list (sorted by uid):");
12786                    printedAnything = true;
12787                    printed = true;
12788                    needSep = true;
12789                }
12790                pw.println(String.format("%sIsolated #%2d: %s",
12791                        "    ", i, r.toString()));
12792            }
12793        }
12794
12795        if (mLruProcesses.size() > 0) {
12796            if (needSep) {
12797                pw.println();
12798            }
12799            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12800                    pw.print(" total, non-act at ");
12801                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12802                    pw.print(", non-svc at ");
12803                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12804                    pw.println("):");
12805            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12806            needSep = true;
12807            printedAnything = true;
12808        }
12809
12810        if (dumpAll || dumpPackage != null) {
12811            synchronized (mPidsSelfLocked) {
12812                boolean printed = false;
12813                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12814                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12815                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12816                        continue;
12817                    }
12818                    if (!printed) {
12819                        if (needSep) pw.println();
12820                        needSep = true;
12821                        pw.println("  PID mappings:");
12822                        printed = true;
12823                        printedAnything = true;
12824                    }
12825                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12826                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12827                }
12828            }
12829        }
12830
12831        if (mForegroundProcesses.size() > 0) {
12832            synchronized (mPidsSelfLocked) {
12833                boolean printed = false;
12834                for (int i=0; i<mForegroundProcesses.size(); i++) {
12835                    ProcessRecord r = mPidsSelfLocked.get(
12836                            mForegroundProcesses.valueAt(i).pid);
12837                    if (dumpPackage != null && (r == null
12838                            || !r.pkgList.containsKey(dumpPackage))) {
12839                        continue;
12840                    }
12841                    if (!printed) {
12842                        if (needSep) pw.println();
12843                        needSep = true;
12844                        pw.println("  Foreground Processes:");
12845                        printed = true;
12846                        printedAnything = true;
12847                    }
12848                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12849                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12850                }
12851            }
12852        }
12853
12854        if (mPersistentStartingProcesses.size() > 0) {
12855            if (needSep) pw.println();
12856            needSep = true;
12857            printedAnything = true;
12858            pw.println("  Persisent processes that are starting:");
12859            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12860                    "Starting Norm", "Restarting PERS", dumpPackage);
12861        }
12862
12863        if (mRemovedProcesses.size() > 0) {
12864            if (needSep) pw.println();
12865            needSep = true;
12866            printedAnything = true;
12867            pw.println("  Processes that are being removed:");
12868            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12869                    "Removed Norm", "Removed PERS", dumpPackage);
12870        }
12871
12872        if (mProcessesOnHold.size() > 0) {
12873            if (needSep) pw.println();
12874            needSep = true;
12875            printedAnything = true;
12876            pw.println("  Processes that are on old until the system is ready:");
12877            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12878                    "OnHold Norm", "OnHold PERS", dumpPackage);
12879        }
12880
12881        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12882
12883        if (mProcessCrashTimes.getMap().size() > 0) {
12884            boolean printed = false;
12885            long now = SystemClock.uptimeMillis();
12886            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12887            final int NP = pmap.size();
12888            for (int ip=0; ip<NP; ip++) {
12889                String pname = pmap.keyAt(ip);
12890                SparseArray<Long> uids = pmap.valueAt(ip);
12891                final int N = uids.size();
12892                for (int i=0; i<N; i++) {
12893                    int puid = uids.keyAt(i);
12894                    ProcessRecord r = mProcessNames.get(pname, puid);
12895                    if (dumpPackage != null && (r == null
12896                            || !r.pkgList.containsKey(dumpPackage))) {
12897                        continue;
12898                    }
12899                    if (!printed) {
12900                        if (needSep) pw.println();
12901                        needSep = true;
12902                        pw.println("  Time since processes crashed:");
12903                        printed = true;
12904                        printedAnything = true;
12905                    }
12906                    pw.print("    Process "); pw.print(pname);
12907                            pw.print(" uid "); pw.print(puid);
12908                            pw.print(": last crashed ");
12909                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12910                            pw.println(" ago");
12911                }
12912            }
12913        }
12914
12915        if (mBadProcesses.getMap().size() > 0) {
12916            boolean printed = false;
12917            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12918            final int NP = pmap.size();
12919            for (int ip=0; ip<NP; ip++) {
12920                String pname = pmap.keyAt(ip);
12921                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12922                final int N = uids.size();
12923                for (int i=0; i<N; i++) {
12924                    int puid = uids.keyAt(i);
12925                    ProcessRecord r = mProcessNames.get(pname, puid);
12926                    if (dumpPackage != null && (r == null
12927                            || !r.pkgList.containsKey(dumpPackage))) {
12928                        continue;
12929                    }
12930                    if (!printed) {
12931                        if (needSep) pw.println();
12932                        needSep = true;
12933                        pw.println("  Bad processes:");
12934                        printedAnything = true;
12935                    }
12936                    BadProcessInfo info = uids.valueAt(i);
12937                    pw.print("    Bad process "); pw.print(pname);
12938                            pw.print(" uid "); pw.print(puid);
12939                            pw.print(": crashed at time "); pw.println(info.time);
12940                    if (info.shortMsg != null) {
12941                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12942                    }
12943                    if (info.longMsg != null) {
12944                        pw.print("      Long msg: "); pw.println(info.longMsg);
12945                    }
12946                    if (info.stack != null) {
12947                        pw.println("      Stack:");
12948                        int lastPos = 0;
12949                        for (int pos=0; pos<info.stack.length(); pos++) {
12950                            if (info.stack.charAt(pos) == '\n') {
12951                                pw.print("        ");
12952                                pw.write(info.stack, lastPos, pos-lastPos);
12953                                pw.println();
12954                                lastPos = pos+1;
12955                            }
12956                        }
12957                        if (lastPos < info.stack.length()) {
12958                            pw.print("        ");
12959                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12960                            pw.println();
12961                        }
12962                    }
12963                }
12964            }
12965        }
12966
12967        if (dumpPackage == null) {
12968            pw.println();
12969            needSep = false;
12970            pw.println("  mStartedUsers:");
12971            for (int i=0; i<mStartedUsers.size(); i++) {
12972                UserStartedState uss = mStartedUsers.valueAt(i);
12973                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12974                        pw.print(": "); uss.dump("", pw);
12975            }
12976            pw.print("  mStartedUserArray: [");
12977            for (int i=0; i<mStartedUserArray.length; i++) {
12978                if (i > 0) pw.print(", ");
12979                pw.print(mStartedUserArray[i]);
12980            }
12981            pw.println("]");
12982            pw.print("  mUserLru: [");
12983            for (int i=0; i<mUserLru.size(); i++) {
12984                if (i > 0) pw.print(", ");
12985                pw.print(mUserLru.get(i));
12986            }
12987            pw.println("]");
12988            if (dumpAll) {
12989                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12990            }
12991            synchronized (mUserProfileGroupIdsSelfLocked) {
12992                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12993                    pw.println("  mUserProfileGroupIds:");
12994                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12995                        pw.print("    User #");
12996                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12997                        pw.print(" -> profile #");
12998                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12999                    }
13000                }
13001            }
13002        }
13003        if (mHomeProcess != null && (dumpPackage == null
13004                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13005            if (needSep) {
13006                pw.println();
13007                needSep = false;
13008            }
13009            pw.println("  mHomeProcess: " + mHomeProcess);
13010        }
13011        if (mPreviousProcess != null && (dumpPackage == null
13012                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13013            if (needSep) {
13014                pw.println();
13015                needSep = false;
13016            }
13017            pw.println("  mPreviousProcess: " + mPreviousProcess);
13018        }
13019        if (dumpAll) {
13020            StringBuilder sb = new StringBuilder(128);
13021            sb.append("  mPreviousProcessVisibleTime: ");
13022            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13023            pw.println(sb);
13024        }
13025        if (mHeavyWeightProcess != null && (dumpPackage == null
13026                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13027            if (needSep) {
13028                pw.println();
13029                needSep = false;
13030            }
13031            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13032        }
13033        if (dumpPackage == null) {
13034            pw.println("  mConfiguration: " + mConfiguration);
13035        }
13036        if (dumpAll) {
13037            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13038            if (mCompatModePackages.getPackages().size() > 0) {
13039                boolean printed = false;
13040                for (Map.Entry<String, Integer> entry
13041                        : mCompatModePackages.getPackages().entrySet()) {
13042                    String pkg = entry.getKey();
13043                    int mode = entry.getValue();
13044                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13045                        continue;
13046                    }
13047                    if (!printed) {
13048                        pw.println("  mScreenCompatPackages:");
13049                        printed = true;
13050                    }
13051                    pw.print("    "); pw.print(pkg); pw.print(": ");
13052                            pw.print(mode); pw.println();
13053                }
13054            }
13055        }
13056        if (dumpPackage == null) {
13057            pw.println("  mWakefulness="
13058                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13059            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13060                    + lockScreenShownToString());
13061            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
13062                    + " mTestPssMode=" + mTestPssMode);
13063        }
13064        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13065                || mOrigWaitForDebugger) {
13066            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13067                    || dumpPackage.equals(mOrigDebugApp)) {
13068                if (needSep) {
13069                    pw.println();
13070                    needSep = false;
13071                }
13072                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13073                        + " mDebugTransient=" + mDebugTransient
13074                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13075            }
13076        }
13077        if (mOpenGlTraceApp != null) {
13078            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13079                if (needSep) {
13080                    pw.println();
13081                    needSep = false;
13082                }
13083                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13084            }
13085        }
13086        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13087                || mProfileFd != null) {
13088            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13089                if (needSep) {
13090                    pw.println();
13091                    needSep = false;
13092                }
13093                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13094                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13095                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13096                        + mAutoStopProfiler);
13097                pw.println("  mProfileType=" + mProfileType);
13098            }
13099        }
13100        if (dumpPackage == null) {
13101            if (mAlwaysFinishActivities || mController != null) {
13102                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13103                        + " mController=" + mController);
13104            }
13105            if (dumpAll) {
13106                pw.println("  Total persistent processes: " + numPers);
13107                pw.println("  mProcessesReady=" + mProcessesReady
13108                        + " mSystemReady=" + mSystemReady
13109                        + " mBooted=" + mBooted
13110                        + " mFactoryTest=" + mFactoryTest);
13111                pw.println("  mBooting=" + mBooting
13112                        + " mCallFinishBooting=" + mCallFinishBooting
13113                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13114                pw.print("  mLastPowerCheckRealtime=");
13115                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13116                        pw.println("");
13117                pw.print("  mLastPowerCheckUptime=");
13118                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13119                        pw.println("");
13120                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13121                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13122                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13123                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13124                        + " (" + mLruProcesses.size() + " total)"
13125                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13126                        + " mNumServiceProcs=" + mNumServiceProcs
13127                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13128                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13129                        + " mLastMemoryLevel" + mLastMemoryLevel
13130                        + " mLastNumProcesses" + mLastNumProcesses);
13131                long now = SystemClock.uptimeMillis();
13132                pw.print("  mLastIdleTime=");
13133                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13134                        pw.print(" mLowRamSinceLastIdle=");
13135                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13136                        pw.println();
13137            }
13138        }
13139
13140        if (!printedAnything) {
13141            pw.println("  (nothing)");
13142        }
13143    }
13144
13145    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13146            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13147        if (mProcessesToGc.size() > 0) {
13148            boolean printed = false;
13149            long now = SystemClock.uptimeMillis();
13150            for (int i=0; i<mProcessesToGc.size(); i++) {
13151                ProcessRecord proc = mProcessesToGc.get(i);
13152                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13153                    continue;
13154                }
13155                if (!printed) {
13156                    if (needSep) pw.println();
13157                    needSep = true;
13158                    pw.println("  Processes that are waiting to GC:");
13159                    printed = true;
13160                }
13161                pw.print("    Process "); pw.println(proc);
13162                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13163                        pw.print(", last gced=");
13164                        pw.print(now-proc.lastRequestedGc);
13165                        pw.print(" ms ago, last lowMem=");
13166                        pw.print(now-proc.lastLowMemory);
13167                        pw.println(" ms ago");
13168
13169            }
13170        }
13171        return needSep;
13172    }
13173
13174    void printOomLevel(PrintWriter pw, String name, int adj) {
13175        pw.print("    ");
13176        if (adj >= 0) {
13177            pw.print(' ');
13178            if (adj < 10) pw.print(' ');
13179        } else {
13180            if (adj > -10) pw.print(' ');
13181        }
13182        pw.print(adj);
13183        pw.print(": ");
13184        pw.print(name);
13185        pw.print(" (");
13186        pw.print(mProcessList.getMemLevel(adj)/1024);
13187        pw.println(" kB)");
13188    }
13189
13190    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13191            int opti, boolean dumpAll) {
13192        boolean needSep = false;
13193
13194        if (mLruProcesses.size() > 0) {
13195            if (needSep) pw.println();
13196            needSep = true;
13197            pw.println("  OOM levels:");
13198            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13199            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13200            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13201            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13202            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13203            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13204            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13205            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13206            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13207            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13208            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13209            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13210            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13211            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13212
13213            if (needSep) pw.println();
13214            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13215                    pw.print(" total, non-act at ");
13216                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13217                    pw.print(", non-svc at ");
13218                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13219                    pw.println("):");
13220            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13221            needSep = true;
13222        }
13223
13224        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13225
13226        pw.println();
13227        pw.println("  mHomeProcess: " + mHomeProcess);
13228        pw.println("  mPreviousProcess: " + mPreviousProcess);
13229        if (mHeavyWeightProcess != null) {
13230            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13231        }
13232
13233        return true;
13234    }
13235
13236    /**
13237     * There are three ways to call this:
13238     *  - no provider specified: dump all the providers
13239     *  - a flattened component name that matched an existing provider was specified as the
13240     *    first arg: dump that one provider
13241     *  - the first arg isn't the flattened component name of an existing provider:
13242     *    dump all providers whose component contains the first arg as a substring
13243     */
13244    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13245            int opti, boolean dumpAll) {
13246        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13247    }
13248
13249    static class ItemMatcher {
13250        ArrayList<ComponentName> components;
13251        ArrayList<String> strings;
13252        ArrayList<Integer> objects;
13253        boolean all;
13254
13255        ItemMatcher() {
13256            all = true;
13257        }
13258
13259        void build(String name) {
13260            ComponentName componentName = ComponentName.unflattenFromString(name);
13261            if (componentName != null) {
13262                if (components == null) {
13263                    components = new ArrayList<ComponentName>();
13264                }
13265                components.add(componentName);
13266                all = false;
13267            } else {
13268                int objectId = 0;
13269                // Not a '/' separated full component name; maybe an object ID?
13270                try {
13271                    objectId = Integer.parseInt(name, 16);
13272                    if (objects == null) {
13273                        objects = new ArrayList<Integer>();
13274                    }
13275                    objects.add(objectId);
13276                    all = false;
13277                } catch (RuntimeException e) {
13278                    // Not an integer; just do string match.
13279                    if (strings == null) {
13280                        strings = new ArrayList<String>();
13281                    }
13282                    strings.add(name);
13283                    all = false;
13284                }
13285            }
13286        }
13287
13288        int build(String[] args, int opti) {
13289            for (; opti<args.length; opti++) {
13290                String name = args[opti];
13291                if ("--".equals(name)) {
13292                    return opti+1;
13293                }
13294                build(name);
13295            }
13296            return opti;
13297        }
13298
13299        boolean match(Object object, ComponentName comp) {
13300            if (all) {
13301                return true;
13302            }
13303            if (components != null) {
13304                for (int i=0; i<components.size(); i++) {
13305                    if (components.get(i).equals(comp)) {
13306                        return true;
13307                    }
13308                }
13309            }
13310            if (objects != null) {
13311                for (int i=0; i<objects.size(); i++) {
13312                    if (System.identityHashCode(object) == objects.get(i)) {
13313                        return true;
13314                    }
13315                }
13316            }
13317            if (strings != null) {
13318                String flat = comp.flattenToString();
13319                for (int i=0; i<strings.size(); i++) {
13320                    if (flat.contains(strings.get(i))) {
13321                        return true;
13322                    }
13323                }
13324            }
13325            return false;
13326        }
13327    }
13328
13329    /**
13330     * There are three things that cmd can be:
13331     *  - a flattened component name that matches an existing activity
13332     *  - the cmd arg isn't the flattened component name of an existing activity:
13333     *    dump all activity whose component contains the cmd as a substring
13334     *  - A hex number of the ActivityRecord object instance.
13335     */
13336    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13337            int opti, boolean dumpAll) {
13338        ArrayList<ActivityRecord> activities;
13339
13340        synchronized (this) {
13341            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13342        }
13343
13344        if (activities.size() <= 0) {
13345            return false;
13346        }
13347
13348        String[] newArgs = new String[args.length - opti];
13349        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13350
13351        TaskRecord lastTask = null;
13352        boolean needSep = false;
13353        for (int i=activities.size()-1; i>=0; i--) {
13354            ActivityRecord r = activities.get(i);
13355            if (needSep) {
13356                pw.println();
13357            }
13358            needSep = true;
13359            synchronized (this) {
13360                if (lastTask != r.task) {
13361                    lastTask = r.task;
13362                    pw.print("TASK "); pw.print(lastTask.affinity);
13363                            pw.print(" id="); pw.println(lastTask.taskId);
13364                    if (dumpAll) {
13365                        lastTask.dump(pw, "  ");
13366                    }
13367                }
13368            }
13369            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13370        }
13371        return true;
13372    }
13373
13374    /**
13375     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13376     * there is a thread associated with the activity.
13377     */
13378    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13379            final ActivityRecord r, String[] args, boolean dumpAll) {
13380        String innerPrefix = prefix + "  ";
13381        synchronized (this) {
13382            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13383                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13384                    pw.print(" pid=");
13385                    if (r.app != null) pw.println(r.app.pid);
13386                    else pw.println("(not running)");
13387            if (dumpAll) {
13388                r.dump(pw, innerPrefix);
13389            }
13390        }
13391        if (r.app != null && r.app.thread != null) {
13392            // flush anything that is already in the PrintWriter since the thread is going
13393            // to write to the file descriptor directly
13394            pw.flush();
13395            try {
13396                TransferPipe tp = new TransferPipe();
13397                try {
13398                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13399                            r.appToken, innerPrefix, args);
13400                    tp.go(fd);
13401                } finally {
13402                    tp.kill();
13403                }
13404            } catch (IOException e) {
13405                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13406            } catch (RemoteException e) {
13407                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13408            }
13409        }
13410    }
13411
13412    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13413            int opti, boolean dumpAll, String dumpPackage) {
13414        boolean needSep = false;
13415        boolean onlyHistory = false;
13416        boolean printedAnything = false;
13417
13418        if ("history".equals(dumpPackage)) {
13419            if (opti < args.length && "-s".equals(args[opti])) {
13420                dumpAll = false;
13421            }
13422            onlyHistory = true;
13423            dumpPackage = null;
13424        }
13425
13426        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13427        if (!onlyHistory && dumpAll) {
13428            if (mRegisteredReceivers.size() > 0) {
13429                boolean printed = false;
13430                Iterator it = mRegisteredReceivers.values().iterator();
13431                while (it.hasNext()) {
13432                    ReceiverList r = (ReceiverList)it.next();
13433                    if (dumpPackage != null && (r.app == null ||
13434                            !dumpPackage.equals(r.app.info.packageName))) {
13435                        continue;
13436                    }
13437                    if (!printed) {
13438                        pw.println("  Registered Receivers:");
13439                        needSep = true;
13440                        printed = true;
13441                        printedAnything = true;
13442                    }
13443                    pw.print("  * "); pw.println(r);
13444                    r.dump(pw, "    ");
13445                }
13446            }
13447
13448            if (mReceiverResolver.dump(pw, needSep ?
13449                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13450                    "    ", dumpPackage, false, false)) {
13451                needSep = true;
13452                printedAnything = true;
13453            }
13454        }
13455
13456        for (BroadcastQueue q : mBroadcastQueues) {
13457            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13458            printedAnything |= needSep;
13459        }
13460
13461        needSep = true;
13462
13463        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13464            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13465                if (needSep) {
13466                    pw.println();
13467                }
13468                needSep = true;
13469                printedAnything = true;
13470                pw.print("  Sticky broadcasts for user ");
13471                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13472                StringBuilder sb = new StringBuilder(128);
13473                for (Map.Entry<String, ArrayList<Intent>> ent
13474                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13475                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13476                    if (dumpAll) {
13477                        pw.println(":");
13478                        ArrayList<Intent> intents = ent.getValue();
13479                        final int N = intents.size();
13480                        for (int i=0; i<N; i++) {
13481                            sb.setLength(0);
13482                            sb.append("    Intent: ");
13483                            intents.get(i).toShortString(sb, false, true, false, false);
13484                            pw.println(sb.toString());
13485                            Bundle bundle = intents.get(i).getExtras();
13486                            if (bundle != null) {
13487                                pw.print("      ");
13488                                pw.println(bundle.toString());
13489                            }
13490                        }
13491                    } else {
13492                        pw.println("");
13493                    }
13494                }
13495            }
13496        }
13497
13498        if (!onlyHistory && dumpAll) {
13499            pw.println();
13500            for (BroadcastQueue queue : mBroadcastQueues) {
13501                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13502                        + queue.mBroadcastsScheduled);
13503            }
13504            pw.println("  mHandler:");
13505            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13506            needSep = true;
13507            printedAnything = true;
13508        }
13509
13510        if (!printedAnything) {
13511            pw.println("  (nothing)");
13512        }
13513    }
13514
13515    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13516            int opti, boolean dumpAll, String dumpPackage) {
13517        boolean needSep;
13518        boolean printedAnything = false;
13519
13520        ItemMatcher matcher = new ItemMatcher();
13521        matcher.build(args, opti);
13522
13523        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13524
13525        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13526        printedAnything |= needSep;
13527
13528        if (mLaunchingProviders.size() > 0) {
13529            boolean printed = false;
13530            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13531                ContentProviderRecord r = mLaunchingProviders.get(i);
13532                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13533                    continue;
13534                }
13535                if (!printed) {
13536                    if (needSep) pw.println();
13537                    needSep = true;
13538                    pw.println("  Launching content providers:");
13539                    printed = true;
13540                    printedAnything = true;
13541                }
13542                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13543                        pw.println(r);
13544            }
13545        }
13546
13547        if (mGrantedUriPermissions.size() > 0) {
13548            boolean printed = false;
13549            int dumpUid = -2;
13550            if (dumpPackage != null) {
13551                try {
13552                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13553                } catch (NameNotFoundException e) {
13554                    dumpUid = -1;
13555                }
13556            }
13557            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13558                int uid = mGrantedUriPermissions.keyAt(i);
13559                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13560                    continue;
13561                }
13562                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13563                if (!printed) {
13564                    if (needSep) pw.println();
13565                    needSep = true;
13566                    pw.println("  Granted Uri Permissions:");
13567                    printed = true;
13568                    printedAnything = true;
13569                }
13570                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13571                for (UriPermission perm : perms.values()) {
13572                    pw.print("    "); pw.println(perm);
13573                    if (dumpAll) {
13574                        perm.dump(pw, "      ");
13575                    }
13576                }
13577            }
13578        }
13579
13580        if (!printedAnything) {
13581            pw.println("  (nothing)");
13582        }
13583    }
13584
13585    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13586            int opti, boolean dumpAll, String dumpPackage) {
13587        boolean printed = false;
13588
13589        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13590
13591        if (mIntentSenderRecords.size() > 0) {
13592            Iterator<WeakReference<PendingIntentRecord>> it
13593                    = mIntentSenderRecords.values().iterator();
13594            while (it.hasNext()) {
13595                WeakReference<PendingIntentRecord> ref = it.next();
13596                PendingIntentRecord rec = ref != null ? ref.get(): null;
13597                if (dumpPackage != null && (rec == null
13598                        || !dumpPackage.equals(rec.key.packageName))) {
13599                    continue;
13600                }
13601                printed = true;
13602                if (rec != null) {
13603                    pw.print("  * "); pw.println(rec);
13604                    if (dumpAll) {
13605                        rec.dump(pw, "    ");
13606                    }
13607                } else {
13608                    pw.print("  * "); pw.println(ref);
13609                }
13610            }
13611        }
13612
13613        if (!printed) {
13614            pw.println("  (nothing)");
13615        }
13616    }
13617
13618    private static final int dumpProcessList(PrintWriter pw,
13619            ActivityManagerService service, List list,
13620            String prefix, String normalLabel, String persistentLabel,
13621            String dumpPackage) {
13622        int numPers = 0;
13623        final int N = list.size()-1;
13624        for (int i=N; i>=0; i--) {
13625            ProcessRecord r = (ProcessRecord)list.get(i);
13626            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13627                continue;
13628            }
13629            pw.println(String.format("%s%s #%2d: %s",
13630                    prefix, (r.persistent ? persistentLabel : normalLabel),
13631                    i, r.toString()));
13632            if (r.persistent) {
13633                numPers++;
13634            }
13635        }
13636        return numPers;
13637    }
13638
13639    private static final boolean dumpProcessOomList(PrintWriter pw,
13640            ActivityManagerService service, List<ProcessRecord> origList,
13641            String prefix, String normalLabel, String persistentLabel,
13642            boolean inclDetails, String dumpPackage) {
13643
13644        ArrayList<Pair<ProcessRecord, Integer>> list
13645                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13646        for (int i=0; i<origList.size(); i++) {
13647            ProcessRecord r = origList.get(i);
13648            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13649                continue;
13650            }
13651            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13652        }
13653
13654        if (list.size() <= 0) {
13655            return false;
13656        }
13657
13658        Comparator<Pair<ProcessRecord, Integer>> comparator
13659                = new Comparator<Pair<ProcessRecord, Integer>>() {
13660            @Override
13661            public int compare(Pair<ProcessRecord, Integer> object1,
13662                    Pair<ProcessRecord, Integer> object2) {
13663                if (object1.first.setAdj != object2.first.setAdj) {
13664                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13665                }
13666                if (object1.second.intValue() != object2.second.intValue()) {
13667                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13668                }
13669                return 0;
13670            }
13671        };
13672
13673        Collections.sort(list, comparator);
13674
13675        final long curRealtime = SystemClock.elapsedRealtime();
13676        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13677        final long curUptime = SystemClock.uptimeMillis();
13678        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13679
13680        for (int i=list.size()-1; i>=0; i--) {
13681            ProcessRecord r = list.get(i).first;
13682            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13683            char schedGroup;
13684            switch (r.setSchedGroup) {
13685                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13686                    schedGroup = 'B';
13687                    break;
13688                case Process.THREAD_GROUP_DEFAULT:
13689                    schedGroup = 'F';
13690                    break;
13691                default:
13692                    schedGroup = '?';
13693                    break;
13694            }
13695            char foreground;
13696            if (r.foregroundActivities) {
13697                foreground = 'A';
13698            } else if (r.foregroundServices) {
13699                foreground = 'S';
13700            } else {
13701                foreground = ' ';
13702            }
13703            String procState = ProcessList.makeProcStateString(r.curProcState);
13704            pw.print(prefix);
13705            pw.print(r.persistent ? persistentLabel : normalLabel);
13706            pw.print(" #");
13707            int num = (origList.size()-1)-list.get(i).second;
13708            if (num < 10) pw.print(' ');
13709            pw.print(num);
13710            pw.print(": ");
13711            pw.print(oomAdj);
13712            pw.print(' ');
13713            pw.print(schedGroup);
13714            pw.print('/');
13715            pw.print(foreground);
13716            pw.print('/');
13717            pw.print(procState);
13718            pw.print(" trm:");
13719            if (r.trimMemoryLevel < 10) pw.print(' ');
13720            pw.print(r.trimMemoryLevel);
13721            pw.print(' ');
13722            pw.print(r.toShortString());
13723            pw.print(" (");
13724            pw.print(r.adjType);
13725            pw.println(')');
13726            if (r.adjSource != null || r.adjTarget != null) {
13727                pw.print(prefix);
13728                pw.print("    ");
13729                if (r.adjTarget instanceof ComponentName) {
13730                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13731                } else if (r.adjTarget != null) {
13732                    pw.print(r.adjTarget.toString());
13733                } else {
13734                    pw.print("{null}");
13735                }
13736                pw.print("<=");
13737                if (r.adjSource instanceof ProcessRecord) {
13738                    pw.print("Proc{");
13739                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13740                    pw.println("}");
13741                } else if (r.adjSource != null) {
13742                    pw.println(r.adjSource.toString());
13743                } else {
13744                    pw.println("{null}");
13745                }
13746            }
13747            if (inclDetails) {
13748                pw.print(prefix);
13749                pw.print("    ");
13750                pw.print("oom: max="); pw.print(r.maxAdj);
13751                pw.print(" curRaw="); pw.print(r.curRawAdj);
13752                pw.print(" setRaw="); pw.print(r.setRawAdj);
13753                pw.print(" cur="); pw.print(r.curAdj);
13754                pw.print(" set="); pw.println(r.setAdj);
13755                pw.print(prefix);
13756                pw.print("    ");
13757                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13758                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13759                pw.print(" lastPss="); pw.print(r.lastPss);
13760                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13761                pw.print(prefix);
13762                pw.print("    ");
13763                pw.print("cached="); pw.print(r.cached);
13764                pw.print(" empty="); pw.print(r.empty);
13765                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13766
13767                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13768                    if (r.lastWakeTime != 0) {
13769                        long wtime;
13770                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13771                        synchronized (stats) {
13772                            wtime = stats.getProcessWakeTime(r.info.uid,
13773                                    r.pid, curRealtime);
13774                        }
13775                        long timeUsed = wtime - r.lastWakeTime;
13776                        pw.print(prefix);
13777                        pw.print("    ");
13778                        pw.print("keep awake over ");
13779                        TimeUtils.formatDuration(realtimeSince, pw);
13780                        pw.print(" used ");
13781                        TimeUtils.formatDuration(timeUsed, pw);
13782                        pw.print(" (");
13783                        pw.print((timeUsed*100)/realtimeSince);
13784                        pw.println("%)");
13785                    }
13786                    if (r.lastCpuTime != 0) {
13787                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13788                        pw.print(prefix);
13789                        pw.print("    ");
13790                        pw.print("run cpu over ");
13791                        TimeUtils.formatDuration(uptimeSince, pw);
13792                        pw.print(" used ");
13793                        TimeUtils.formatDuration(timeUsed, pw);
13794                        pw.print(" (");
13795                        pw.print((timeUsed*100)/uptimeSince);
13796                        pw.println("%)");
13797                    }
13798                }
13799            }
13800        }
13801        return true;
13802    }
13803
13804    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13805            String[] args) {
13806        ArrayList<ProcessRecord> procs;
13807        synchronized (this) {
13808            if (args != null && args.length > start
13809                    && args[start].charAt(0) != '-') {
13810                procs = new ArrayList<ProcessRecord>();
13811                int pid = -1;
13812                try {
13813                    pid = Integer.parseInt(args[start]);
13814                } catch (NumberFormatException e) {
13815                }
13816                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13817                    ProcessRecord proc = mLruProcesses.get(i);
13818                    if (proc.pid == pid) {
13819                        procs.add(proc);
13820                    } else if (allPkgs && proc.pkgList != null
13821                            && proc.pkgList.containsKey(args[start])) {
13822                        procs.add(proc);
13823                    } else if (proc.processName.equals(args[start])) {
13824                        procs.add(proc);
13825                    }
13826                }
13827                if (procs.size() <= 0) {
13828                    return null;
13829                }
13830            } else {
13831                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13832            }
13833        }
13834        return procs;
13835    }
13836
13837    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13838            PrintWriter pw, String[] args) {
13839        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13840        if (procs == null) {
13841            pw.println("No process found for: " + args[0]);
13842            return;
13843        }
13844
13845        long uptime = SystemClock.uptimeMillis();
13846        long realtime = SystemClock.elapsedRealtime();
13847        pw.println("Applications Graphics Acceleration Info:");
13848        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13849
13850        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13851            ProcessRecord r = procs.get(i);
13852            if (r.thread != null) {
13853                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13854                pw.flush();
13855                try {
13856                    TransferPipe tp = new TransferPipe();
13857                    try {
13858                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13859                        tp.go(fd);
13860                    } finally {
13861                        tp.kill();
13862                    }
13863                } catch (IOException e) {
13864                    pw.println("Failure while dumping the app: " + r);
13865                    pw.flush();
13866                } catch (RemoteException e) {
13867                    pw.println("Got a RemoteException while dumping the app " + r);
13868                    pw.flush();
13869                }
13870            }
13871        }
13872    }
13873
13874    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13875        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13876        if (procs == null) {
13877            pw.println("No process found for: " + args[0]);
13878            return;
13879        }
13880
13881        pw.println("Applications Database Info:");
13882
13883        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13884            ProcessRecord r = procs.get(i);
13885            if (r.thread != null) {
13886                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13887                pw.flush();
13888                try {
13889                    TransferPipe tp = new TransferPipe();
13890                    try {
13891                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13892                        tp.go(fd);
13893                    } finally {
13894                        tp.kill();
13895                    }
13896                } catch (IOException e) {
13897                    pw.println("Failure while dumping the app: " + r);
13898                    pw.flush();
13899                } catch (RemoteException e) {
13900                    pw.println("Got a RemoteException while dumping the app " + r);
13901                    pw.flush();
13902                }
13903            }
13904        }
13905    }
13906
13907    final static class MemItem {
13908        final boolean isProc;
13909        final String label;
13910        final String shortLabel;
13911        final long pss;
13912        final int id;
13913        final boolean hasActivities;
13914        ArrayList<MemItem> subitems;
13915
13916        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13917                boolean _hasActivities) {
13918            isProc = true;
13919            label = _label;
13920            shortLabel = _shortLabel;
13921            pss = _pss;
13922            id = _id;
13923            hasActivities = _hasActivities;
13924        }
13925
13926        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13927            isProc = false;
13928            label = _label;
13929            shortLabel = _shortLabel;
13930            pss = _pss;
13931            id = _id;
13932            hasActivities = false;
13933        }
13934    }
13935
13936    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13937            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13938        if (sort && !isCompact) {
13939            Collections.sort(items, new Comparator<MemItem>() {
13940                @Override
13941                public int compare(MemItem lhs, MemItem rhs) {
13942                    if (lhs.pss < rhs.pss) {
13943                        return 1;
13944                    } else if (lhs.pss > rhs.pss) {
13945                        return -1;
13946                    }
13947                    return 0;
13948                }
13949            });
13950        }
13951
13952        for (int i=0; i<items.size(); i++) {
13953            MemItem mi = items.get(i);
13954            if (!isCompact) {
13955                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13956            } else if (mi.isProc) {
13957                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13958                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13959                pw.println(mi.hasActivities ? ",a" : ",e");
13960            } else {
13961                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13962                pw.println(mi.pss);
13963            }
13964            if (mi.subitems != null) {
13965                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13966                        true, isCompact);
13967            }
13968        }
13969    }
13970
13971    // These are in KB.
13972    static final long[] DUMP_MEM_BUCKETS = new long[] {
13973        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13974        120*1024, 160*1024, 200*1024,
13975        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13976        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13977    };
13978
13979    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13980            boolean stackLike) {
13981        int start = label.lastIndexOf('.');
13982        if (start >= 0) start++;
13983        else start = 0;
13984        int end = label.length();
13985        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13986            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13987                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13988                out.append(bucket);
13989                out.append(stackLike ? "MB." : "MB ");
13990                out.append(label, start, end);
13991                return;
13992            }
13993        }
13994        out.append(memKB/1024);
13995        out.append(stackLike ? "MB." : "MB ");
13996        out.append(label, start, end);
13997    }
13998
13999    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14000            ProcessList.NATIVE_ADJ,
14001            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14002            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14003            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14004            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14005            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14006            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14007    };
14008    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14009            "Native",
14010            "System", "Persistent", "Persistent Service", "Foreground",
14011            "Visible", "Perceptible",
14012            "Heavy Weight", "Backup",
14013            "A Services", "Home",
14014            "Previous", "B Services", "Cached"
14015    };
14016    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14017            "native",
14018            "sys", "pers", "persvc", "fore",
14019            "vis", "percept",
14020            "heavy", "backup",
14021            "servicea", "home",
14022            "prev", "serviceb", "cached"
14023    };
14024
14025    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14026            long realtime, boolean isCheckinRequest, boolean isCompact) {
14027        if (isCheckinRequest || isCompact) {
14028            // short checkin version
14029            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14030        } else {
14031            pw.println("Applications Memory Usage (kB):");
14032            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14033        }
14034    }
14035
14036    private static final int KSM_SHARED = 0;
14037    private static final int KSM_SHARING = 1;
14038    private static final int KSM_UNSHARED = 2;
14039    private static final int KSM_VOLATILE = 3;
14040
14041    private final long[] getKsmInfo() {
14042        long[] longOut = new long[4];
14043        final int[] SINGLE_LONG_FORMAT = new int[] {
14044            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14045        };
14046        long[] longTmp = new long[1];
14047        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14048                SINGLE_LONG_FORMAT, null, longTmp, null);
14049        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14050        longTmp[0] = 0;
14051        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14052                SINGLE_LONG_FORMAT, null, longTmp, null);
14053        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14054        longTmp[0] = 0;
14055        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14056                SINGLE_LONG_FORMAT, null, longTmp, null);
14057        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14058        longTmp[0] = 0;
14059        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14060                SINGLE_LONG_FORMAT, null, longTmp, null);
14061        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14062        return longOut;
14063    }
14064
14065    final void dumpApplicationMemoryUsage(FileDescriptor fd,
14066            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14067        boolean dumpDetails = false;
14068        boolean dumpFullDetails = false;
14069        boolean dumpDalvik = false;
14070        boolean oomOnly = false;
14071        boolean isCompact = false;
14072        boolean localOnly = false;
14073        boolean packages = false;
14074
14075        int opti = 0;
14076        while (opti < args.length) {
14077            String opt = args[opti];
14078            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14079                break;
14080            }
14081            opti++;
14082            if ("-a".equals(opt)) {
14083                dumpDetails = true;
14084                dumpFullDetails = true;
14085                dumpDalvik = true;
14086            } else if ("-d".equals(opt)) {
14087                dumpDalvik = true;
14088            } else if ("-c".equals(opt)) {
14089                isCompact = true;
14090            } else if ("--oom".equals(opt)) {
14091                oomOnly = true;
14092            } else if ("--local".equals(opt)) {
14093                localOnly = true;
14094            } else if ("--package".equals(opt)) {
14095                packages = true;
14096            } else if ("-h".equals(opt)) {
14097                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
14098                pw.println("  -a: include all available information for each process.");
14099                pw.println("  -d: include dalvik details when dumping process details.");
14100                pw.println("  -c: dump in a compact machine-parseable representation.");
14101                pw.println("  --oom: only show processes organized by oom adj.");
14102                pw.println("  --local: only collect details locally, don't call process.");
14103                pw.println("  --package: interpret process arg as package, dumping all");
14104                pw.println("             processes that have loaded that package.");
14105                pw.println("If [process] is specified it can be the name or ");
14106                pw.println("pid of a specific process to dump.");
14107                return;
14108            } else {
14109                pw.println("Unknown argument: " + opt + "; use -h for help");
14110            }
14111        }
14112
14113        final boolean isCheckinRequest = scanArgs(args, "--checkin");
14114        long uptime = SystemClock.uptimeMillis();
14115        long realtime = SystemClock.elapsedRealtime();
14116        final long[] tmpLong = new long[1];
14117
14118        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14119        if (procs == null) {
14120            // No Java processes.  Maybe they want to print a native process.
14121            if (args != null && args.length > opti
14122                    && args[opti].charAt(0) != '-') {
14123                ArrayList<ProcessCpuTracker.Stats> nativeProcs
14124                        = new ArrayList<ProcessCpuTracker.Stats>();
14125                updateCpuStatsNow();
14126                int findPid = -1;
14127                try {
14128                    findPid = Integer.parseInt(args[opti]);
14129                } catch (NumberFormatException e) {
14130                }
14131                synchronized (mProcessCpuTracker) {
14132                    final int N = mProcessCpuTracker.countStats();
14133                    for (int i=0; i<N; i++) {
14134                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14135                        if (st.pid == findPid || (st.baseName != null
14136                                && st.baseName.equals(args[opti]))) {
14137                            nativeProcs.add(st);
14138                        }
14139                    }
14140                }
14141                if (nativeProcs.size() > 0) {
14142                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14143                            isCompact);
14144                    Debug.MemoryInfo mi = null;
14145                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14146                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14147                        final int pid = r.pid;
14148                        if (!isCheckinRequest && dumpDetails) {
14149                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14150                        }
14151                        if (mi == null) {
14152                            mi = new Debug.MemoryInfo();
14153                        }
14154                        if (dumpDetails || (!brief && !oomOnly)) {
14155                            Debug.getMemoryInfo(pid, mi);
14156                        } else {
14157                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14158                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14159                        }
14160                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14161                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14162                        if (isCheckinRequest) {
14163                            pw.println();
14164                        }
14165                    }
14166                    return;
14167                }
14168            }
14169            pw.println("No process found for: " + args[opti]);
14170            return;
14171        }
14172
14173        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14174            dumpDetails = true;
14175        }
14176
14177        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14178
14179        String[] innerArgs = new String[args.length-opti];
14180        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14181
14182        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14183        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14184        long nativePss = 0;
14185        long dalvikPss = 0;
14186        long otherPss = 0;
14187        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14188
14189        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14190        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14191                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14192
14193        long totalPss = 0;
14194        long cachedPss = 0;
14195
14196        Debug.MemoryInfo mi = null;
14197        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14198            final ProcessRecord r = procs.get(i);
14199            final IApplicationThread thread;
14200            final int pid;
14201            final int oomAdj;
14202            final boolean hasActivities;
14203            synchronized (this) {
14204                thread = r.thread;
14205                pid = r.pid;
14206                oomAdj = r.getSetAdjWithServices();
14207                hasActivities = r.activities.size() > 0;
14208            }
14209            if (thread != null) {
14210                if (!isCheckinRequest && dumpDetails) {
14211                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14212                }
14213                if (mi == null) {
14214                    mi = new Debug.MemoryInfo();
14215                }
14216                if (dumpDetails || (!brief && !oomOnly)) {
14217                    Debug.getMemoryInfo(pid, mi);
14218                } else {
14219                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14220                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14221                }
14222                if (dumpDetails) {
14223                    if (localOnly) {
14224                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14225                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14226                        if (isCheckinRequest) {
14227                            pw.println();
14228                        }
14229                    } else {
14230                        try {
14231                            pw.flush();
14232                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14233                                    dumpDalvik, innerArgs);
14234                        } catch (RemoteException e) {
14235                            if (!isCheckinRequest) {
14236                                pw.println("Got RemoteException!");
14237                                pw.flush();
14238                            }
14239                        }
14240                    }
14241                }
14242
14243                final long myTotalPss = mi.getTotalPss();
14244                final long myTotalUss = mi.getTotalUss();
14245
14246                synchronized (this) {
14247                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14248                        // Record this for posterity if the process has been stable.
14249                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14250                    }
14251                }
14252
14253                if (!isCheckinRequest && mi != null) {
14254                    totalPss += myTotalPss;
14255                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14256                            (hasActivities ? " / activities)" : ")"),
14257                            r.processName, myTotalPss, pid, hasActivities);
14258                    procMems.add(pssItem);
14259                    procMemsMap.put(pid, pssItem);
14260
14261                    nativePss += mi.nativePss;
14262                    dalvikPss += mi.dalvikPss;
14263                    otherPss += mi.otherPss;
14264                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14265                        long mem = mi.getOtherPss(j);
14266                        miscPss[j] += mem;
14267                        otherPss -= mem;
14268                    }
14269
14270                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14271                        cachedPss += myTotalPss;
14272                    }
14273
14274                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14275                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14276                                || oomIndex == (oomPss.length-1)) {
14277                            oomPss[oomIndex] += myTotalPss;
14278                            if (oomProcs[oomIndex] == null) {
14279                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14280                            }
14281                            oomProcs[oomIndex].add(pssItem);
14282                            break;
14283                        }
14284                    }
14285                }
14286            }
14287        }
14288
14289        long nativeProcTotalPss = 0;
14290
14291        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14292            // If we are showing aggregations, also look for native processes to
14293            // include so that our aggregations are more accurate.
14294            updateCpuStatsNow();
14295            mi = null;
14296            synchronized (mProcessCpuTracker) {
14297                final int N = mProcessCpuTracker.countStats();
14298                for (int i=0; i<N; i++) {
14299                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14300                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14301                        if (mi == null) {
14302                            mi = new Debug.MemoryInfo();
14303                        }
14304                        if (!brief && !oomOnly) {
14305                            Debug.getMemoryInfo(st.pid, mi);
14306                        } else {
14307                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14308                            mi.nativePrivateDirty = (int)tmpLong[0];
14309                        }
14310
14311                        final long myTotalPss = mi.getTotalPss();
14312                        totalPss += myTotalPss;
14313                        nativeProcTotalPss += myTotalPss;
14314
14315                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14316                                st.name, myTotalPss, st.pid, false);
14317                        procMems.add(pssItem);
14318
14319                        nativePss += mi.nativePss;
14320                        dalvikPss += mi.dalvikPss;
14321                        otherPss += mi.otherPss;
14322                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14323                            long mem = mi.getOtherPss(j);
14324                            miscPss[j] += mem;
14325                            otherPss -= mem;
14326                        }
14327                        oomPss[0] += myTotalPss;
14328                        if (oomProcs[0] == null) {
14329                            oomProcs[0] = new ArrayList<MemItem>();
14330                        }
14331                        oomProcs[0].add(pssItem);
14332                    }
14333                }
14334            }
14335
14336            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14337
14338            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14339            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14340            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14341            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14342                String label = Debug.MemoryInfo.getOtherLabel(j);
14343                catMems.add(new MemItem(label, label, miscPss[j], j));
14344            }
14345
14346            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14347            for (int j=0; j<oomPss.length; j++) {
14348                if (oomPss[j] != 0) {
14349                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14350                            : DUMP_MEM_OOM_LABEL[j];
14351                    MemItem item = new MemItem(label, label, oomPss[j],
14352                            DUMP_MEM_OOM_ADJ[j]);
14353                    item.subitems = oomProcs[j];
14354                    oomMems.add(item);
14355                }
14356            }
14357
14358            if (!brief && !oomOnly && !isCompact) {
14359                pw.println();
14360                pw.println("Total PSS by process:");
14361                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14362                pw.println();
14363            }
14364            if (!isCompact) {
14365                pw.println("Total PSS by OOM adjustment:");
14366            }
14367            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14368            if (!brief && !oomOnly) {
14369                PrintWriter out = categoryPw != null ? categoryPw : pw;
14370                if (!isCompact) {
14371                    out.println();
14372                    out.println("Total PSS by category:");
14373                }
14374                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14375            }
14376            if (!isCompact) {
14377                pw.println();
14378            }
14379            MemInfoReader memInfo = new MemInfoReader();
14380            memInfo.readMemInfo();
14381            if (nativeProcTotalPss > 0) {
14382                synchronized (this) {
14383                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14384                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14385                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14386                }
14387            }
14388            if (!brief) {
14389                if (!isCompact) {
14390                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14391                    pw.print(" kB (status ");
14392                    switch (mLastMemoryLevel) {
14393                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14394                            pw.println("normal)");
14395                            break;
14396                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14397                            pw.println("moderate)");
14398                            break;
14399                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14400                            pw.println("low)");
14401                            break;
14402                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14403                            pw.println("critical)");
14404                            break;
14405                        default:
14406                            pw.print(mLastMemoryLevel);
14407                            pw.println(")");
14408                            break;
14409                    }
14410                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14411                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14412                            pw.print(cachedPss); pw.print(" cached pss + ");
14413                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14414                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14415                } else {
14416                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14417                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14418                            + memInfo.getFreeSizeKb()); pw.print(",");
14419                    pw.println(totalPss - cachedPss);
14420                }
14421            }
14422            if (!isCompact) {
14423                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14424                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14425                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14426                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14427                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14428                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14429                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14430            }
14431            if (!brief) {
14432                if (memInfo.getZramTotalSizeKb() != 0) {
14433                    if (!isCompact) {
14434                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14435                                pw.print(" kB physical used for ");
14436                                pw.print(memInfo.getSwapTotalSizeKb()
14437                                        - memInfo.getSwapFreeSizeKb());
14438                                pw.print(" kB in swap (");
14439                                pw.print(memInfo.getSwapTotalSizeKb());
14440                                pw.println(" kB total swap)");
14441                    } else {
14442                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14443                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14444                                pw.println(memInfo.getSwapFreeSizeKb());
14445                    }
14446                }
14447                final long[] ksm = getKsmInfo();
14448                if (!isCompact) {
14449                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14450                            || ksm[KSM_VOLATILE] != 0) {
14451                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14452                                pw.print(" kB saved from shared ");
14453                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14454                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14455                                pw.print(" kB unshared; ");
14456                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14457                    }
14458                    pw.print("   Tuning: ");
14459                    pw.print(ActivityManager.staticGetMemoryClass());
14460                    pw.print(" (large ");
14461                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14462                    pw.print("), oom ");
14463                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14464                    pw.print(" kB");
14465                    pw.print(", restore limit ");
14466                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14467                    pw.print(" kB");
14468                    if (ActivityManager.isLowRamDeviceStatic()) {
14469                        pw.print(" (low-ram)");
14470                    }
14471                    if (ActivityManager.isHighEndGfx()) {
14472                        pw.print(" (high-end-gfx)");
14473                    }
14474                    pw.println();
14475                } else {
14476                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14477                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14478                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14479                    pw.print("tuning,");
14480                    pw.print(ActivityManager.staticGetMemoryClass());
14481                    pw.print(',');
14482                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14483                    pw.print(',');
14484                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14485                    if (ActivityManager.isLowRamDeviceStatic()) {
14486                        pw.print(",low-ram");
14487                    }
14488                    if (ActivityManager.isHighEndGfx()) {
14489                        pw.print(",high-end-gfx");
14490                    }
14491                    pw.println();
14492                }
14493            }
14494        }
14495    }
14496
14497    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14498            long memtrack, String name) {
14499        sb.append("  ");
14500        sb.append(ProcessList.makeOomAdjString(oomAdj));
14501        sb.append(' ');
14502        sb.append(ProcessList.makeProcStateString(procState));
14503        sb.append(' ');
14504        ProcessList.appendRamKb(sb, pss);
14505        sb.append(" kB: ");
14506        sb.append(name);
14507        if (memtrack > 0) {
14508            sb.append(" (");
14509            sb.append(memtrack);
14510            sb.append(" kB memtrack)");
14511        }
14512    }
14513
14514    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14515        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14516        sb.append(" (pid ");
14517        sb.append(mi.pid);
14518        sb.append(") ");
14519        sb.append(mi.adjType);
14520        sb.append('\n');
14521        if (mi.adjReason != null) {
14522            sb.append("                      ");
14523            sb.append(mi.adjReason);
14524            sb.append('\n');
14525        }
14526    }
14527
14528    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14529        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14530        for (int i=0, N=memInfos.size(); i<N; i++) {
14531            ProcessMemInfo mi = memInfos.get(i);
14532            infoMap.put(mi.pid, mi);
14533        }
14534        updateCpuStatsNow();
14535        long[] memtrackTmp = new long[1];
14536        synchronized (mProcessCpuTracker) {
14537            final int N = mProcessCpuTracker.countStats();
14538            for (int i=0; i<N; i++) {
14539                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14540                if (st.vsize > 0) {
14541                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14542                    if (pss > 0) {
14543                        if (infoMap.indexOfKey(st.pid) < 0) {
14544                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14545                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14546                            mi.pss = pss;
14547                            mi.memtrack = memtrackTmp[0];
14548                            memInfos.add(mi);
14549                        }
14550                    }
14551                }
14552            }
14553        }
14554
14555        long totalPss = 0;
14556        long totalMemtrack = 0;
14557        for (int i=0, N=memInfos.size(); i<N; i++) {
14558            ProcessMemInfo mi = memInfos.get(i);
14559            if (mi.pss == 0) {
14560                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14561                mi.memtrack = memtrackTmp[0];
14562            }
14563            totalPss += mi.pss;
14564            totalMemtrack += mi.memtrack;
14565        }
14566        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14567            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14568                if (lhs.oomAdj != rhs.oomAdj) {
14569                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14570                }
14571                if (lhs.pss != rhs.pss) {
14572                    return lhs.pss < rhs.pss ? 1 : -1;
14573                }
14574                return 0;
14575            }
14576        });
14577
14578        StringBuilder tag = new StringBuilder(128);
14579        StringBuilder stack = new StringBuilder(128);
14580        tag.append("Low on memory -- ");
14581        appendMemBucket(tag, totalPss, "total", false);
14582        appendMemBucket(stack, totalPss, "total", true);
14583
14584        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14585        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14586        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14587
14588        boolean firstLine = true;
14589        int lastOomAdj = Integer.MIN_VALUE;
14590        long extraNativeRam = 0;
14591        long extraNativeMemtrack = 0;
14592        long cachedPss = 0;
14593        for (int i=0, N=memInfos.size(); i<N; i++) {
14594            ProcessMemInfo mi = memInfos.get(i);
14595
14596            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14597                cachedPss += mi.pss;
14598            }
14599
14600            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14601                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14602                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14603                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14604                if (lastOomAdj != mi.oomAdj) {
14605                    lastOomAdj = mi.oomAdj;
14606                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14607                        tag.append(" / ");
14608                    }
14609                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14610                        if (firstLine) {
14611                            stack.append(":");
14612                            firstLine = false;
14613                        }
14614                        stack.append("\n\t at ");
14615                    } else {
14616                        stack.append("$");
14617                    }
14618                } else {
14619                    tag.append(" ");
14620                    stack.append("$");
14621                }
14622                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14623                    appendMemBucket(tag, mi.pss, mi.name, false);
14624                }
14625                appendMemBucket(stack, mi.pss, mi.name, true);
14626                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14627                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14628                    stack.append("(");
14629                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14630                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14631                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14632                            stack.append(":");
14633                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14634                        }
14635                    }
14636                    stack.append(")");
14637                }
14638            }
14639
14640            appendMemInfo(fullNativeBuilder, mi);
14641            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14642                // The short form only has native processes that are >= 512K.
14643                if (mi.pss >= 512) {
14644                    appendMemInfo(shortNativeBuilder, mi);
14645                } else {
14646                    extraNativeRam += mi.pss;
14647                    extraNativeMemtrack += mi.memtrack;
14648                }
14649            } else {
14650                // Short form has all other details, but if we have collected RAM
14651                // from smaller native processes let's dump a summary of that.
14652                if (extraNativeRam > 0) {
14653                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14654                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14655                    shortNativeBuilder.append('\n');
14656                    extraNativeRam = 0;
14657                }
14658                appendMemInfo(fullJavaBuilder, mi);
14659            }
14660        }
14661
14662        fullJavaBuilder.append("           ");
14663        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14664        fullJavaBuilder.append(" kB: TOTAL");
14665        if (totalMemtrack > 0) {
14666            fullJavaBuilder.append(" (");
14667            fullJavaBuilder.append(totalMemtrack);
14668            fullJavaBuilder.append(" kB memtrack)");
14669        } else {
14670        }
14671        fullJavaBuilder.append("\n");
14672
14673        MemInfoReader memInfo = new MemInfoReader();
14674        memInfo.readMemInfo();
14675        final long[] infos = memInfo.getRawInfo();
14676
14677        StringBuilder memInfoBuilder = new StringBuilder(1024);
14678        Debug.getMemInfo(infos);
14679        memInfoBuilder.append("  MemInfo: ");
14680        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14681        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14682        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14683        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14684        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14685        memInfoBuilder.append("           ");
14686        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14687        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14688        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14689        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14690        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14691            memInfoBuilder.append("  ZRAM: ");
14692            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14693            memInfoBuilder.append(" kB RAM, ");
14694            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14695            memInfoBuilder.append(" kB swap total, ");
14696            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14697            memInfoBuilder.append(" kB swap free\n");
14698        }
14699        final long[] ksm = getKsmInfo();
14700        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14701                || ksm[KSM_VOLATILE] != 0) {
14702            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14703            memInfoBuilder.append(" kB saved from shared ");
14704            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14705            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14706            memInfoBuilder.append(" kB unshared; ");
14707            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14708        }
14709        memInfoBuilder.append("  Free RAM: ");
14710        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14711                + memInfo.getFreeSizeKb());
14712        memInfoBuilder.append(" kB\n");
14713        memInfoBuilder.append("  Used RAM: ");
14714        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14715        memInfoBuilder.append(" kB\n");
14716        memInfoBuilder.append("  Lost RAM: ");
14717        memInfoBuilder.append(memInfo.getTotalSizeKb()
14718                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14719                - memInfo.getKernelUsedSizeKb());
14720        memInfoBuilder.append(" kB\n");
14721        Slog.i(TAG, "Low on memory:");
14722        Slog.i(TAG, shortNativeBuilder.toString());
14723        Slog.i(TAG, fullJavaBuilder.toString());
14724        Slog.i(TAG, memInfoBuilder.toString());
14725
14726        StringBuilder dropBuilder = new StringBuilder(1024);
14727        /*
14728        StringWriter oomSw = new StringWriter();
14729        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14730        StringWriter catSw = new StringWriter();
14731        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14732        String[] emptyArgs = new String[] { };
14733        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14734        oomPw.flush();
14735        String oomString = oomSw.toString();
14736        */
14737        dropBuilder.append("Low on memory:");
14738        dropBuilder.append(stack);
14739        dropBuilder.append('\n');
14740        dropBuilder.append(fullNativeBuilder);
14741        dropBuilder.append(fullJavaBuilder);
14742        dropBuilder.append('\n');
14743        dropBuilder.append(memInfoBuilder);
14744        dropBuilder.append('\n');
14745        /*
14746        dropBuilder.append(oomString);
14747        dropBuilder.append('\n');
14748        */
14749        StringWriter catSw = new StringWriter();
14750        synchronized (ActivityManagerService.this) {
14751            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14752            String[] emptyArgs = new String[] { };
14753            catPw.println();
14754            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14755            catPw.println();
14756            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14757                    false, false, null);
14758            catPw.println();
14759            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14760            catPw.flush();
14761        }
14762        dropBuilder.append(catSw.toString());
14763        addErrorToDropBox("lowmem", null, "system_server", null,
14764                null, tag.toString(), dropBuilder.toString(), null, null);
14765        //Slog.i(TAG, "Sent to dropbox:");
14766        //Slog.i(TAG, dropBuilder.toString());
14767        synchronized (ActivityManagerService.this) {
14768            long now = SystemClock.uptimeMillis();
14769            if (mLastMemUsageReportTime < now) {
14770                mLastMemUsageReportTime = now;
14771            }
14772        }
14773    }
14774
14775    /**
14776     * Searches array of arguments for the specified string
14777     * @param args array of argument strings
14778     * @param value value to search for
14779     * @return true if the value is contained in the array
14780     */
14781    private static boolean scanArgs(String[] args, String value) {
14782        if (args != null) {
14783            for (String arg : args) {
14784                if (value.equals(arg)) {
14785                    return true;
14786                }
14787            }
14788        }
14789        return false;
14790    }
14791
14792    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14793            ContentProviderRecord cpr, boolean always) {
14794        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14795
14796        if (!inLaunching || always) {
14797            synchronized (cpr) {
14798                cpr.launchingApp = null;
14799                cpr.notifyAll();
14800            }
14801            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14802            String names[] = cpr.info.authority.split(";");
14803            for (int j = 0; j < names.length; j++) {
14804                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14805            }
14806        }
14807
14808        for (int i=0; i<cpr.connections.size(); i++) {
14809            ContentProviderConnection conn = cpr.connections.get(i);
14810            if (conn.waiting) {
14811                // If this connection is waiting for the provider, then we don't
14812                // need to mess with its process unless we are always removing
14813                // or for some reason the provider is not currently launching.
14814                if (inLaunching && !always) {
14815                    continue;
14816                }
14817            }
14818            ProcessRecord capp = conn.client;
14819            conn.dead = true;
14820            if (conn.stableCount > 0) {
14821                if (!capp.persistent && capp.thread != null
14822                        && capp.pid != 0
14823                        && capp.pid != MY_PID) {
14824                    capp.kill("depends on provider "
14825                            + cpr.name.flattenToShortString()
14826                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14827                }
14828            } else if (capp.thread != null && conn.provider.provider != null) {
14829                try {
14830                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14831                } catch (RemoteException e) {
14832                }
14833                // In the protocol here, we don't expect the client to correctly
14834                // clean up this connection, we'll just remove it.
14835                cpr.connections.remove(i);
14836                if (conn.client.conProviders.remove(conn)) {
14837                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14838                }
14839            }
14840        }
14841
14842        if (inLaunching && always) {
14843            mLaunchingProviders.remove(cpr);
14844        }
14845        return inLaunching;
14846    }
14847
14848    /**
14849     * Main code for cleaning up a process when it has gone away.  This is
14850     * called both as a result of the process dying, or directly when stopping
14851     * a process when running in single process mode.
14852     *
14853     * @return Returns true if the given process has been restarted, so the
14854     * app that was passed in must remain on the process lists.
14855     */
14856    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14857            boolean restarting, boolean allowRestart, int index) {
14858        if (index >= 0) {
14859            removeLruProcessLocked(app);
14860            ProcessList.remove(app.pid);
14861        }
14862
14863        mProcessesToGc.remove(app);
14864        mPendingPssProcesses.remove(app);
14865
14866        // Dismiss any open dialogs.
14867        if (app.crashDialog != null && !app.forceCrashReport) {
14868            app.crashDialog.dismiss();
14869            app.crashDialog = null;
14870        }
14871        if (app.anrDialog != null) {
14872            app.anrDialog.dismiss();
14873            app.anrDialog = null;
14874        }
14875        if (app.waitDialog != null) {
14876            app.waitDialog.dismiss();
14877            app.waitDialog = null;
14878        }
14879
14880        app.crashing = false;
14881        app.notResponding = false;
14882
14883        app.resetPackageList(mProcessStats);
14884        app.unlinkDeathRecipient();
14885        app.makeInactive(mProcessStats);
14886        app.waitingToKill = null;
14887        app.forcingToForeground = null;
14888        updateProcessForegroundLocked(app, false, false);
14889        app.foregroundActivities = false;
14890        app.hasShownUi = false;
14891        app.treatLikeActivity = false;
14892        app.hasAboveClient = false;
14893        app.hasClientActivities = false;
14894
14895        mServices.killServicesLocked(app, allowRestart);
14896
14897        boolean restart = false;
14898
14899        // Remove published content providers.
14900        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14901            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14902            final boolean always = app.bad || !allowRestart;
14903            if (removeDyingProviderLocked(app, cpr, always) || always) {
14904                // We left the provider in the launching list, need to
14905                // restart it.
14906                restart = true;
14907            }
14908
14909            cpr.provider = null;
14910            cpr.proc = null;
14911        }
14912        app.pubProviders.clear();
14913
14914        // Take care of any launching providers waiting for this process.
14915        if (checkAppInLaunchingProvidersLocked(app, false)) {
14916            restart = true;
14917        }
14918
14919        // Unregister from connected content providers.
14920        if (!app.conProviders.isEmpty()) {
14921            for (int i=0; i<app.conProviders.size(); i++) {
14922                ContentProviderConnection conn = app.conProviders.get(i);
14923                conn.provider.connections.remove(conn);
14924                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
14925                        conn.provider.name);
14926            }
14927            app.conProviders.clear();
14928        }
14929
14930        // At this point there may be remaining entries in mLaunchingProviders
14931        // where we were the only one waiting, so they are no longer of use.
14932        // Look for these and clean up if found.
14933        // XXX Commented out for now.  Trying to figure out a way to reproduce
14934        // the actual situation to identify what is actually going on.
14935        if (false) {
14936            for (int i=0; i<mLaunchingProviders.size(); i++) {
14937                ContentProviderRecord cpr = (ContentProviderRecord)
14938                        mLaunchingProviders.get(i);
14939                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14940                    synchronized (cpr) {
14941                        cpr.launchingApp = null;
14942                        cpr.notifyAll();
14943                    }
14944                }
14945            }
14946        }
14947
14948        skipCurrentReceiverLocked(app);
14949
14950        // Unregister any receivers.
14951        for (int i=app.receivers.size()-1; i>=0; i--) {
14952            removeReceiverLocked(app.receivers.valueAt(i));
14953        }
14954        app.receivers.clear();
14955
14956        // If the app is undergoing backup, tell the backup manager about it
14957        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14958            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14959                    + mBackupTarget.appInfo + " died during backup");
14960            try {
14961                IBackupManager bm = IBackupManager.Stub.asInterface(
14962                        ServiceManager.getService(Context.BACKUP_SERVICE));
14963                bm.agentDisconnected(app.info.packageName);
14964            } catch (RemoteException e) {
14965                // can't happen; backup manager is local
14966            }
14967        }
14968
14969        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14970            ProcessChangeItem item = mPendingProcessChanges.get(i);
14971            if (item.pid == app.pid) {
14972                mPendingProcessChanges.remove(i);
14973                mAvailProcessChanges.add(item);
14974            }
14975        }
14976        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14977
14978        // If the caller is restarting this app, then leave it in its
14979        // current lists and let the caller take care of it.
14980        if (restarting) {
14981            return false;
14982        }
14983
14984        if (!app.persistent || app.isolated) {
14985            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14986                    "Removing non-persistent process during cleanup: " + app);
14987            mProcessNames.remove(app.processName, app.uid);
14988            mIsolatedProcesses.remove(app.uid);
14989            if (mHeavyWeightProcess == app) {
14990                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14991                        mHeavyWeightProcess.userId, 0));
14992                mHeavyWeightProcess = null;
14993            }
14994        } else if (!app.removed) {
14995            // This app is persistent, so we need to keep its record around.
14996            // If it is not already on the pending app list, add it there
14997            // and start a new process for it.
14998            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14999                mPersistentStartingProcesses.add(app);
15000                restart = true;
15001            }
15002        }
15003        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
15004                "Clean-up removing on hold: " + app);
15005        mProcessesOnHold.remove(app);
15006
15007        if (app == mHomeProcess) {
15008            mHomeProcess = null;
15009        }
15010        if (app == mPreviousProcess) {
15011            mPreviousProcess = null;
15012        }
15013
15014        if (restart && !app.isolated) {
15015            // We have components that still need to be running in the
15016            // process, so re-launch it.
15017            if (index < 0) {
15018                ProcessList.remove(app.pid);
15019            }
15020            mProcessNames.put(app.processName, app.uid, app);
15021            startProcessLocked(app, "restart", app.processName);
15022            return true;
15023        } else if (app.pid > 0 && app.pid != MY_PID) {
15024            // Goodbye!
15025            boolean removed;
15026            synchronized (mPidsSelfLocked) {
15027                mPidsSelfLocked.remove(app.pid);
15028                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15029            }
15030            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15031            if (app.isolated) {
15032                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15033            }
15034            app.setPid(0);
15035        }
15036        return false;
15037    }
15038
15039    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15040        // Look through the content providers we are waiting to have launched,
15041        // and if any run in this process then either schedule a restart of
15042        // the process or kill the client waiting for it if this process has
15043        // gone bad.
15044        int NL = mLaunchingProviders.size();
15045        boolean restart = false;
15046        for (int i=0; i<NL; i++) {
15047            ContentProviderRecord cpr = mLaunchingProviders.get(i);
15048            if (cpr.launchingApp == app) {
15049                if (!alwaysBad && !app.bad) {
15050                    restart = true;
15051                } else {
15052                    removeDyingProviderLocked(app, cpr, true);
15053                    // cpr should have been removed from mLaunchingProviders
15054                    NL = mLaunchingProviders.size();
15055                    i--;
15056                }
15057            }
15058        }
15059        return restart;
15060    }
15061
15062    // =========================================================
15063    // SERVICES
15064    // =========================================================
15065
15066    @Override
15067    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15068            int flags) {
15069        enforceNotIsolatedCaller("getServices");
15070        synchronized (this) {
15071            return mServices.getRunningServiceInfoLocked(maxNum, flags);
15072        }
15073    }
15074
15075    @Override
15076    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15077        enforceNotIsolatedCaller("getRunningServiceControlPanel");
15078        synchronized (this) {
15079            return mServices.getRunningServiceControlPanelLocked(name);
15080        }
15081    }
15082
15083    @Override
15084    public ComponentName startService(IApplicationThread caller, Intent service,
15085            String resolvedType, int userId) {
15086        enforceNotIsolatedCaller("startService");
15087        // Refuse possible leaked file descriptors
15088        if (service != null && service.hasFileDescriptors() == true) {
15089            throw new IllegalArgumentException("File descriptors passed in Intent");
15090        }
15091
15092        if (DEBUG_SERVICE)
15093            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
15094        synchronized(this) {
15095            final int callingPid = Binder.getCallingPid();
15096            final int callingUid = Binder.getCallingUid();
15097            final long origId = Binder.clearCallingIdentity();
15098            ComponentName res = mServices.startServiceLocked(caller, service,
15099                    resolvedType, callingPid, callingUid, userId);
15100            Binder.restoreCallingIdentity(origId);
15101            return res;
15102        }
15103    }
15104
15105    ComponentName startServiceInPackage(int uid,
15106            Intent service, String resolvedType, int userId) {
15107        synchronized(this) {
15108            if (DEBUG_SERVICE)
15109                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
15110            final long origId = Binder.clearCallingIdentity();
15111            ComponentName res = mServices.startServiceLocked(null, service,
15112                    resolvedType, -1, uid, userId);
15113            Binder.restoreCallingIdentity(origId);
15114            return res;
15115        }
15116    }
15117
15118    @Override
15119    public int stopService(IApplicationThread caller, Intent service,
15120            String resolvedType, int userId) {
15121        enforceNotIsolatedCaller("stopService");
15122        // Refuse possible leaked file descriptors
15123        if (service != null && service.hasFileDescriptors() == true) {
15124            throw new IllegalArgumentException("File descriptors passed in Intent");
15125        }
15126
15127        synchronized(this) {
15128            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15129        }
15130    }
15131
15132    @Override
15133    public IBinder peekService(Intent service, String resolvedType) {
15134        enforceNotIsolatedCaller("peekService");
15135        // Refuse possible leaked file descriptors
15136        if (service != null && service.hasFileDescriptors() == true) {
15137            throw new IllegalArgumentException("File descriptors passed in Intent");
15138        }
15139        synchronized(this) {
15140            return mServices.peekServiceLocked(service, resolvedType);
15141        }
15142    }
15143
15144    @Override
15145    public boolean stopServiceToken(ComponentName className, IBinder token,
15146            int startId) {
15147        synchronized(this) {
15148            return mServices.stopServiceTokenLocked(className, token, startId);
15149        }
15150    }
15151
15152    @Override
15153    public void setServiceForeground(ComponentName className, IBinder token,
15154            int id, Notification notification, boolean removeNotification) {
15155        synchronized(this) {
15156            mServices.setServiceForegroundLocked(className, token, id, notification,
15157                    removeNotification);
15158        }
15159    }
15160
15161    @Override
15162    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15163            boolean requireFull, String name, String callerPackage) {
15164        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15165                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15166    }
15167
15168    int unsafeConvertIncomingUser(int userId) {
15169        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15170                ? mCurrentUserId : userId;
15171    }
15172
15173    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15174            int allowMode, String name, String callerPackage) {
15175        final int callingUserId = UserHandle.getUserId(callingUid);
15176        if (callingUserId == userId) {
15177            return userId;
15178        }
15179
15180        // Note that we may be accessing mCurrentUserId outside of a lock...
15181        // shouldn't be a big deal, if this is being called outside
15182        // of a locked context there is intrinsically a race with
15183        // the value the caller will receive and someone else changing it.
15184        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15185        // we will switch to the calling user if access to the current user fails.
15186        int targetUserId = unsafeConvertIncomingUser(userId);
15187
15188        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15189            final boolean allow;
15190            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15191                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15192                // If the caller has this permission, they always pass go.  And collect $200.
15193                allow = true;
15194            } else if (allowMode == ALLOW_FULL_ONLY) {
15195                // We require full access, sucks to be you.
15196                allow = false;
15197            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15198                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15199                // If the caller does not have either permission, they are always doomed.
15200                allow = false;
15201            } else if (allowMode == ALLOW_NON_FULL) {
15202                // We are blanket allowing non-full access, you lucky caller!
15203                allow = true;
15204            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15205                // We may or may not allow this depending on whether the two users are
15206                // in the same profile.
15207                synchronized (mUserProfileGroupIdsSelfLocked) {
15208                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15209                            UserInfo.NO_PROFILE_GROUP_ID);
15210                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15211                            UserInfo.NO_PROFILE_GROUP_ID);
15212                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15213                            && callingProfile == targetProfile;
15214                }
15215            } else {
15216                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15217            }
15218            if (!allow) {
15219                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15220                    // In this case, they would like to just execute as their
15221                    // owner user instead of failing.
15222                    targetUserId = callingUserId;
15223                } else {
15224                    StringBuilder builder = new StringBuilder(128);
15225                    builder.append("Permission Denial: ");
15226                    builder.append(name);
15227                    if (callerPackage != null) {
15228                        builder.append(" from ");
15229                        builder.append(callerPackage);
15230                    }
15231                    builder.append(" asks to run as user ");
15232                    builder.append(userId);
15233                    builder.append(" but is calling from user ");
15234                    builder.append(UserHandle.getUserId(callingUid));
15235                    builder.append("; this requires ");
15236                    builder.append(INTERACT_ACROSS_USERS_FULL);
15237                    if (allowMode != ALLOW_FULL_ONLY) {
15238                        builder.append(" or ");
15239                        builder.append(INTERACT_ACROSS_USERS);
15240                    }
15241                    String msg = builder.toString();
15242                    Slog.w(TAG, msg);
15243                    throw new SecurityException(msg);
15244                }
15245            }
15246        }
15247        if (!allowAll && targetUserId < 0) {
15248            throw new IllegalArgumentException(
15249                    "Call does not support special user #" + targetUserId);
15250        }
15251        // Check shell permission
15252        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15253            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15254                    targetUserId)) {
15255                throw new SecurityException("Shell does not have permission to access user "
15256                        + targetUserId + "\n " + Debug.getCallers(3));
15257            }
15258        }
15259        return targetUserId;
15260    }
15261
15262    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15263            String className, int flags) {
15264        boolean result = false;
15265        // For apps that don't have pre-defined UIDs, check for permission
15266        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15267            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15268                if (ActivityManager.checkUidPermission(
15269                        INTERACT_ACROSS_USERS,
15270                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15271                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15272                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15273                            + " requests FLAG_SINGLE_USER, but app does not hold "
15274                            + INTERACT_ACROSS_USERS;
15275                    Slog.w(TAG, msg);
15276                    throw new SecurityException(msg);
15277                }
15278                // Permission passed
15279                result = true;
15280            }
15281        } else if ("system".equals(componentProcessName)) {
15282            result = true;
15283        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15284            // Phone app and persistent apps are allowed to export singleuser providers.
15285            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15286                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15287        }
15288        if (DEBUG_MU) {
15289            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15290                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15291        }
15292        return result;
15293    }
15294
15295    /**
15296     * Checks to see if the caller is in the same app as the singleton
15297     * component, or the component is in a special app. It allows special apps
15298     * to export singleton components but prevents exporting singleton
15299     * components for regular apps.
15300     */
15301    boolean isValidSingletonCall(int callingUid, int componentUid) {
15302        int componentAppId = UserHandle.getAppId(componentUid);
15303        return UserHandle.isSameApp(callingUid, componentUid)
15304                || componentAppId == Process.SYSTEM_UID
15305                || componentAppId == Process.PHONE_UID
15306                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15307                        == PackageManager.PERMISSION_GRANTED;
15308    }
15309
15310    public int bindService(IApplicationThread caller, IBinder token,
15311            Intent service, String resolvedType,
15312            IServiceConnection connection, int flags, int userId) {
15313        enforceNotIsolatedCaller("bindService");
15314
15315        // Refuse possible leaked file descriptors
15316        if (service != null && service.hasFileDescriptors() == true) {
15317            throw new IllegalArgumentException("File descriptors passed in Intent");
15318        }
15319
15320        synchronized(this) {
15321            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15322                    connection, flags, userId);
15323        }
15324    }
15325
15326    public boolean unbindService(IServiceConnection connection) {
15327        synchronized (this) {
15328            return mServices.unbindServiceLocked(connection);
15329        }
15330    }
15331
15332    public void publishService(IBinder token, Intent intent, IBinder service) {
15333        // Refuse possible leaked file descriptors
15334        if (intent != null && intent.hasFileDescriptors() == true) {
15335            throw new IllegalArgumentException("File descriptors passed in Intent");
15336        }
15337
15338        synchronized(this) {
15339            if (!(token instanceof ServiceRecord)) {
15340                throw new IllegalArgumentException("Invalid service token");
15341            }
15342            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15343        }
15344    }
15345
15346    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15347        // Refuse possible leaked file descriptors
15348        if (intent != null && intent.hasFileDescriptors() == true) {
15349            throw new IllegalArgumentException("File descriptors passed in Intent");
15350        }
15351
15352        synchronized(this) {
15353            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15354        }
15355    }
15356
15357    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15358        synchronized(this) {
15359            if (!(token instanceof ServiceRecord)) {
15360                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15361                throw new IllegalArgumentException("Invalid service token");
15362            }
15363            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15364        }
15365    }
15366
15367    // =========================================================
15368    // BACKUP AND RESTORE
15369    // =========================================================
15370
15371    // Cause the target app to be launched if necessary and its backup agent
15372    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15373    // activity manager to announce its creation.
15374    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15375        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15376        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15377
15378        synchronized(this) {
15379            // !!! TODO: currently no check here that we're already bound
15380            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15381            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15382            synchronized (stats) {
15383                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15384            }
15385
15386            // Backup agent is now in use, its package can't be stopped.
15387            try {
15388                AppGlobals.getPackageManager().setPackageStoppedState(
15389                        app.packageName, false, UserHandle.getUserId(app.uid));
15390            } catch (RemoteException e) {
15391            } catch (IllegalArgumentException e) {
15392                Slog.w(TAG, "Failed trying to unstop package "
15393                        + app.packageName + ": " + e);
15394            }
15395
15396            BackupRecord r = new BackupRecord(ss, app, backupMode);
15397            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15398                    ? new ComponentName(app.packageName, app.backupAgentName)
15399                    : new ComponentName("android", "FullBackupAgent");
15400            // startProcessLocked() returns existing proc's record if it's already running
15401            ProcessRecord proc = startProcessLocked(app.processName, app,
15402                    false, 0, "backup", hostingName, false, false, false);
15403            if (proc == null) {
15404                Slog.e(TAG, "Unable to start backup agent process " + r);
15405                return false;
15406            }
15407
15408            r.app = proc;
15409            mBackupTarget = r;
15410            mBackupAppName = app.packageName;
15411
15412            // Try not to kill the process during backup
15413            updateOomAdjLocked(proc);
15414
15415            // If the process is already attached, schedule the creation of the backup agent now.
15416            // If it is not yet live, this will be done when it attaches to the framework.
15417            if (proc.thread != null) {
15418                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15419                try {
15420                    proc.thread.scheduleCreateBackupAgent(app,
15421                            compatibilityInfoForPackageLocked(app), backupMode);
15422                } catch (RemoteException e) {
15423                    // Will time out on the backup manager side
15424                }
15425            } else {
15426                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15427            }
15428            // Invariants: at this point, the target app process exists and the application
15429            // is either already running or in the process of coming up.  mBackupTarget and
15430            // mBackupAppName describe the app, so that when it binds back to the AM we
15431            // know that it's scheduled for a backup-agent operation.
15432        }
15433
15434        return true;
15435    }
15436
15437    @Override
15438    public void clearPendingBackup() {
15439        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15440        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15441
15442        synchronized (this) {
15443            mBackupTarget = null;
15444            mBackupAppName = null;
15445        }
15446    }
15447
15448    // A backup agent has just come up
15449    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15450        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15451                + " = " + agent);
15452
15453        synchronized(this) {
15454            if (!agentPackageName.equals(mBackupAppName)) {
15455                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15456                return;
15457            }
15458        }
15459
15460        long oldIdent = Binder.clearCallingIdentity();
15461        try {
15462            IBackupManager bm = IBackupManager.Stub.asInterface(
15463                    ServiceManager.getService(Context.BACKUP_SERVICE));
15464            bm.agentConnected(agentPackageName, agent);
15465        } catch (RemoteException e) {
15466            // can't happen; the backup manager service is local
15467        } catch (Exception e) {
15468            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15469            e.printStackTrace();
15470        } finally {
15471            Binder.restoreCallingIdentity(oldIdent);
15472        }
15473    }
15474
15475    // done with this agent
15476    public void unbindBackupAgent(ApplicationInfo appInfo) {
15477        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15478        if (appInfo == null) {
15479            Slog.w(TAG, "unbind backup agent for null app");
15480            return;
15481        }
15482
15483        synchronized(this) {
15484            try {
15485                if (mBackupAppName == null) {
15486                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15487                    return;
15488                }
15489
15490                if (!mBackupAppName.equals(appInfo.packageName)) {
15491                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15492                    return;
15493                }
15494
15495                // Not backing this app up any more; reset its OOM adjustment
15496                final ProcessRecord proc = mBackupTarget.app;
15497                updateOomAdjLocked(proc);
15498
15499                // If the app crashed during backup, 'thread' will be null here
15500                if (proc.thread != null) {
15501                    try {
15502                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15503                                compatibilityInfoForPackageLocked(appInfo));
15504                    } catch (Exception e) {
15505                        Slog.e(TAG, "Exception when unbinding backup agent:");
15506                        e.printStackTrace();
15507                    }
15508                }
15509            } finally {
15510                mBackupTarget = null;
15511                mBackupAppName = null;
15512            }
15513        }
15514    }
15515    // =========================================================
15516    // BROADCASTS
15517    // =========================================================
15518
15519    private final List getStickiesLocked(String action, IntentFilter filter,
15520            List cur, int userId) {
15521        final ContentResolver resolver = mContext.getContentResolver();
15522        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15523        if (stickies == null) {
15524            return cur;
15525        }
15526        final ArrayList<Intent> list = stickies.get(action);
15527        if (list == null) {
15528            return cur;
15529        }
15530        int N = list.size();
15531        for (int i=0; i<N; i++) {
15532            Intent intent = list.get(i);
15533            if (filter.match(resolver, intent, true, TAG) >= 0) {
15534                if (cur == null) {
15535                    cur = new ArrayList<Intent>();
15536                }
15537                cur.add(intent);
15538            }
15539        }
15540        return cur;
15541    }
15542
15543    boolean isPendingBroadcastProcessLocked(int pid) {
15544        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15545                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15546    }
15547
15548    void skipPendingBroadcastLocked(int pid) {
15549            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15550            for (BroadcastQueue queue : mBroadcastQueues) {
15551                queue.skipPendingBroadcastLocked(pid);
15552            }
15553    }
15554
15555    // The app just attached; send any pending broadcasts that it should receive
15556    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15557        boolean didSomething = false;
15558        for (BroadcastQueue queue : mBroadcastQueues) {
15559            didSomething |= queue.sendPendingBroadcastsLocked(app);
15560        }
15561        return didSomething;
15562    }
15563
15564    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15565            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15566        enforceNotIsolatedCaller("registerReceiver");
15567        int callingUid;
15568        int callingPid;
15569        synchronized(this) {
15570            ProcessRecord callerApp = null;
15571            if (caller != null) {
15572                callerApp = getRecordForAppLocked(caller);
15573                if (callerApp == null) {
15574                    throw new SecurityException(
15575                            "Unable to find app for caller " + caller
15576                            + " (pid=" + Binder.getCallingPid()
15577                            + ") when registering receiver " + receiver);
15578                }
15579                if (callerApp.info.uid != Process.SYSTEM_UID &&
15580                        !callerApp.pkgList.containsKey(callerPackage) &&
15581                        !"android".equals(callerPackage)) {
15582                    throw new SecurityException("Given caller package " + callerPackage
15583                            + " is not running in process " + callerApp);
15584                }
15585                callingUid = callerApp.info.uid;
15586                callingPid = callerApp.pid;
15587            } else {
15588                callerPackage = null;
15589                callingUid = Binder.getCallingUid();
15590                callingPid = Binder.getCallingPid();
15591            }
15592
15593            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15594                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15595
15596            List allSticky = null;
15597
15598            // Look for any matching sticky broadcasts...
15599            Iterator actions = filter.actionsIterator();
15600            if (actions != null) {
15601                while (actions.hasNext()) {
15602                    String action = (String)actions.next();
15603                    allSticky = getStickiesLocked(action, filter, allSticky,
15604                            UserHandle.USER_ALL);
15605                    allSticky = getStickiesLocked(action, filter, allSticky,
15606                            UserHandle.getUserId(callingUid));
15607                }
15608            } else {
15609                allSticky = getStickiesLocked(null, filter, allSticky,
15610                        UserHandle.USER_ALL);
15611                allSticky = getStickiesLocked(null, filter, allSticky,
15612                        UserHandle.getUserId(callingUid));
15613            }
15614
15615            // The first sticky in the list is returned directly back to
15616            // the client.
15617            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15618
15619            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15620                    + ": " + sticky);
15621
15622            if (receiver == null) {
15623                return sticky;
15624            }
15625
15626            ReceiverList rl
15627                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15628            if (rl == null) {
15629                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15630                        userId, receiver);
15631                if (rl.app != null) {
15632                    rl.app.receivers.add(rl);
15633                } else {
15634                    try {
15635                        receiver.asBinder().linkToDeath(rl, 0);
15636                    } catch (RemoteException e) {
15637                        return sticky;
15638                    }
15639                    rl.linkedToDeath = true;
15640                }
15641                mRegisteredReceivers.put(receiver.asBinder(), rl);
15642            } else if (rl.uid != callingUid) {
15643                throw new IllegalArgumentException(
15644                        "Receiver requested to register for uid " + callingUid
15645                        + " was previously registered for uid " + rl.uid);
15646            } else if (rl.pid != callingPid) {
15647                throw new IllegalArgumentException(
15648                        "Receiver requested to register for pid " + callingPid
15649                        + " was previously registered for pid " + rl.pid);
15650            } else if (rl.userId != userId) {
15651                throw new IllegalArgumentException(
15652                        "Receiver requested to register for user " + userId
15653                        + " was previously registered for user " + rl.userId);
15654            }
15655            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15656                    permission, callingUid, userId);
15657            rl.add(bf);
15658            if (!bf.debugCheck()) {
15659                Slog.w(TAG, "==> For Dynamic broadast");
15660            }
15661            mReceiverResolver.addFilter(bf);
15662
15663            // Enqueue broadcasts for all existing stickies that match
15664            // this filter.
15665            if (allSticky != null) {
15666                ArrayList receivers = new ArrayList();
15667                receivers.add(bf);
15668
15669                int N = allSticky.size();
15670                for (int i=0; i<N; i++) {
15671                    Intent intent = (Intent)allSticky.get(i);
15672                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15673                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15674                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15675                            null, null, false, true, true, -1);
15676                    queue.enqueueParallelBroadcastLocked(r);
15677                    queue.scheduleBroadcastsLocked();
15678                }
15679            }
15680
15681            return sticky;
15682        }
15683    }
15684
15685    public void unregisterReceiver(IIntentReceiver receiver) {
15686        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15687
15688        final long origId = Binder.clearCallingIdentity();
15689        try {
15690            boolean doTrim = false;
15691
15692            synchronized(this) {
15693                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15694                if (rl != null) {
15695                    if (rl.curBroadcast != null) {
15696                        BroadcastRecord r = rl.curBroadcast;
15697                        final boolean doNext = finishReceiverLocked(
15698                                receiver.asBinder(), r.resultCode, r.resultData,
15699                                r.resultExtras, r.resultAbort);
15700                        if (doNext) {
15701                            doTrim = true;
15702                            r.queue.processNextBroadcast(false);
15703                        }
15704                    }
15705
15706                    if (rl.app != null) {
15707                        rl.app.receivers.remove(rl);
15708                    }
15709                    removeReceiverLocked(rl);
15710                    if (rl.linkedToDeath) {
15711                        rl.linkedToDeath = false;
15712                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15713                    }
15714                }
15715            }
15716
15717            // If we actually concluded any broadcasts, we might now be able
15718            // to trim the recipients' apps from our working set
15719            if (doTrim) {
15720                trimApplications();
15721                return;
15722            }
15723
15724        } finally {
15725            Binder.restoreCallingIdentity(origId);
15726        }
15727    }
15728
15729    void removeReceiverLocked(ReceiverList rl) {
15730        mRegisteredReceivers.remove(rl.receiver.asBinder());
15731        int N = rl.size();
15732        for (int i=0; i<N; i++) {
15733            mReceiverResolver.removeFilter(rl.get(i));
15734        }
15735    }
15736
15737    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15738        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15739            ProcessRecord r = mLruProcesses.get(i);
15740            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15741                try {
15742                    r.thread.dispatchPackageBroadcast(cmd, packages);
15743                } catch (RemoteException ex) {
15744                }
15745            }
15746        }
15747    }
15748
15749    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15750            int callingUid, int[] users) {
15751        List<ResolveInfo> receivers = null;
15752        try {
15753            HashSet<ComponentName> singleUserReceivers = null;
15754            boolean scannedFirstReceivers = false;
15755            for (int user : users) {
15756                // Skip users that have Shell restrictions
15757                if (callingUid == Process.SHELL_UID
15758                        && getUserManagerLocked().hasUserRestriction(
15759                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15760                    continue;
15761                }
15762                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15763                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15764                if (user != 0 && newReceivers != null) {
15765                    // If this is not the primary user, we need to check for
15766                    // any receivers that should be filtered out.
15767                    for (int i=0; i<newReceivers.size(); i++) {
15768                        ResolveInfo ri = newReceivers.get(i);
15769                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15770                            newReceivers.remove(i);
15771                            i--;
15772                        }
15773                    }
15774                }
15775                if (newReceivers != null && newReceivers.size() == 0) {
15776                    newReceivers = null;
15777                }
15778                if (receivers == null) {
15779                    receivers = newReceivers;
15780                } else if (newReceivers != null) {
15781                    // We need to concatenate the additional receivers
15782                    // found with what we have do far.  This would be easy,
15783                    // but we also need to de-dup any receivers that are
15784                    // singleUser.
15785                    if (!scannedFirstReceivers) {
15786                        // Collect any single user receivers we had already retrieved.
15787                        scannedFirstReceivers = true;
15788                        for (int i=0; i<receivers.size(); i++) {
15789                            ResolveInfo ri = receivers.get(i);
15790                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15791                                ComponentName cn = new ComponentName(
15792                                        ri.activityInfo.packageName, ri.activityInfo.name);
15793                                if (singleUserReceivers == null) {
15794                                    singleUserReceivers = new HashSet<ComponentName>();
15795                                }
15796                                singleUserReceivers.add(cn);
15797                            }
15798                        }
15799                    }
15800                    // Add the new results to the existing results, tracking
15801                    // and de-dupping single user receivers.
15802                    for (int i=0; i<newReceivers.size(); i++) {
15803                        ResolveInfo ri = newReceivers.get(i);
15804                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15805                            ComponentName cn = new ComponentName(
15806                                    ri.activityInfo.packageName, ri.activityInfo.name);
15807                            if (singleUserReceivers == null) {
15808                                singleUserReceivers = new HashSet<ComponentName>();
15809                            }
15810                            if (!singleUserReceivers.contains(cn)) {
15811                                singleUserReceivers.add(cn);
15812                                receivers.add(ri);
15813                            }
15814                        } else {
15815                            receivers.add(ri);
15816                        }
15817                    }
15818                }
15819            }
15820        } catch (RemoteException ex) {
15821            // pm is in same process, this will never happen.
15822        }
15823        return receivers;
15824    }
15825
15826    private final int broadcastIntentLocked(ProcessRecord callerApp,
15827            String callerPackage, Intent intent, String resolvedType,
15828            IIntentReceiver resultTo, int resultCode, String resultData,
15829            Bundle map, String requiredPermission, int appOp,
15830            boolean ordered, boolean sticky, int callingPid, int callingUid,
15831            int userId) {
15832        intent = new Intent(intent);
15833
15834        // By default broadcasts do not go to stopped apps.
15835        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15836
15837        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15838            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15839            + " ordered=" + ordered + " userid=" + userId);
15840        if ((resultTo != null) && !ordered) {
15841            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15842        }
15843
15844        userId = handleIncomingUser(callingPid, callingUid, userId,
15845                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15846
15847        // Make sure that the user who is receiving this broadcast is running.
15848        // If not, we will just skip it. Make an exception for shutdown broadcasts
15849        // and upgrade steps.
15850
15851        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15852            if ((callingUid != Process.SYSTEM_UID
15853                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15854                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15855                Slog.w(TAG, "Skipping broadcast of " + intent
15856                        + ": user " + userId + " is stopped");
15857                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15858            }
15859        }
15860
15861        /*
15862         * Prevent non-system code (defined here to be non-persistent
15863         * processes) from sending protected broadcasts.
15864         */
15865        int callingAppId = UserHandle.getAppId(callingUid);
15866        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15867            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15868            || callingAppId == Process.NFC_UID || callingUid == 0) {
15869            // Always okay.
15870        } else if (callerApp == null || !callerApp.persistent) {
15871            try {
15872                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15873                        intent.getAction())) {
15874                    String msg = "Permission Denial: not allowed to send broadcast "
15875                            + intent.getAction() + " from pid="
15876                            + callingPid + ", uid=" + callingUid;
15877                    Slog.w(TAG, msg);
15878                    throw new SecurityException(msg);
15879                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15880                    // Special case for compatibility: we don't want apps to send this,
15881                    // but historically it has not been protected and apps may be using it
15882                    // to poke their own app widget.  So, instead of making it protected,
15883                    // just limit it to the caller.
15884                    if (callerApp == null) {
15885                        String msg = "Permission Denial: not allowed to send broadcast "
15886                                + intent.getAction() + " from unknown caller.";
15887                        Slog.w(TAG, msg);
15888                        throw new SecurityException(msg);
15889                    } else if (intent.getComponent() != null) {
15890                        // They are good enough to send to an explicit component...  verify
15891                        // it is being sent to the calling app.
15892                        if (!intent.getComponent().getPackageName().equals(
15893                                callerApp.info.packageName)) {
15894                            String msg = "Permission Denial: not allowed to send broadcast "
15895                                    + intent.getAction() + " to "
15896                                    + intent.getComponent().getPackageName() + " from "
15897                                    + callerApp.info.packageName;
15898                            Slog.w(TAG, msg);
15899                            throw new SecurityException(msg);
15900                        }
15901                    } else {
15902                        // Limit broadcast to their own package.
15903                        intent.setPackage(callerApp.info.packageName);
15904                    }
15905                }
15906            } catch (RemoteException e) {
15907                Slog.w(TAG, "Remote exception", e);
15908                return ActivityManager.BROADCAST_SUCCESS;
15909            }
15910        }
15911
15912        final String action = intent.getAction();
15913        if (action != null) {
15914            switch (action) {
15915                case Intent.ACTION_UID_REMOVED:
15916                case Intent.ACTION_PACKAGE_REMOVED:
15917                case Intent.ACTION_PACKAGE_CHANGED:
15918                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15919                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15920                    // Handle special intents: if this broadcast is from the package
15921                    // manager about a package being removed, we need to remove all of
15922                    // its activities from the history stack.
15923                    if (checkComponentPermission(
15924                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15925                            callingPid, callingUid, -1, true)
15926                            != PackageManager.PERMISSION_GRANTED) {
15927                        String msg = "Permission Denial: " + intent.getAction()
15928                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15929                                + ", uid=" + callingUid + ")"
15930                                + " requires "
15931                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15932                        Slog.w(TAG, msg);
15933                        throw new SecurityException(msg);
15934                    }
15935                    switch (action) {
15936                        case Intent.ACTION_UID_REMOVED:
15937                            final Bundle intentExtras = intent.getExtras();
15938                            final int uid = intentExtras != null
15939                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15940                            if (uid >= 0) {
15941                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15942                                synchronized (bs) {
15943                                    bs.removeUidStatsLocked(uid);
15944                                }
15945                                mAppOpsService.uidRemoved(uid);
15946                            }
15947                            break;
15948                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15949                            // If resources are unavailable just force stop all those packages
15950                            // and flush the attribute cache as well.
15951                            String list[] =
15952                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15953                            if (list != null && list.length > 0) {
15954                                for (int i = 0; i < list.length; i++) {
15955                                    forceStopPackageLocked(list[i], -1, false, true, true,
15956                                            false, false, userId, "storage unmount");
15957                                }
15958                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15959                                sendPackageBroadcastLocked(
15960                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15961                                        userId);
15962                            }
15963                            break;
15964                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15965                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15966                            break;
15967                        case Intent.ACTION_PACKAGE_REMOVED:
15968                        case Intent.ACTION_PACKAGE_CHANGED:
15969                            Uri data = intent.getData();
15970                            String ssp;
15971                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15972                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15973                                boolean fullUninstall = removed &&
15974                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15975                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15976                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15977                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15978                                            false, true, true, false, fullUninstall, userId,
15979                                            removed ? "pkg removed" : "pkg changed");
15980                                }
15981                                if (removed) {
15982                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15983                                            new String[] {ssp}, userId);
15984                                    if (fullUninstall) {
15985                                        mAppOpsService.packageRemoved(
15986                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15987
15988                                        // Remove all permissions granted from/to this package
15989                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15990
15991                                        removeTasksByPackageNameLocked(ssp, userId);
15992                                        if (userId == UserHandle.USER_OWNER) {
15993                                            mTaskPersister.removeFromPackageCache(ssp);
15994                                        }
15995                                    }
15996                                } else {
15997                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15998                                    if (userId == UserHandle.USER_OWNER) {
15999                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16000                                    }
16001                                }
16002                            }
16003                            break;
16004                    }
16005                    break;
16006                case Intent.ACTION_PACKAGE_ADDED:
16007                    // Special case for adding a package: by default turn on compatibility mode.
16008                    Uri data = intent.getData();
16009                    String ssp;
16010                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16011                        final boolean replacing =
16012                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16013                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16014
16015                        if (replacing) {
16016                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16017                        }
16018                        if (userId == UserHandle.USER_OWNER) {
16019                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16020                        }
16021                    }
16022                    break;
16023                case Intent.ACTION_TIMEZONE_CHANGED:
16024                    // If this is the time zone changed action, queue up a message that will reset
16025                    // the timezone of all currently running processes. This message will get
16026                    // queued up before the broadcast happens.
16027                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16028                    break;
16029                case Intent.ACTION_TIME_CHANGED:
16030                    // If the user set the time, let all running processes know.
16031                    final int is24Hour =
16032                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16033                                    : 0;
16034                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16035                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16036                    synchronized (stats) {
16037                        stats.noteCurrentTimeChangedLocked();
16038                    }
16039                    break;
16040                case Intent.ACTION_CLEAR_DNS_CACHE:
16041                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16042                    break;
16043                case Proxy.PROXY_CHANGE_ACTION:
16044                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16045                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16046                    break;
16047            }
16048        }
16049
16050        // Add to the sticky list if requested.
16051        if (sticky) {
16052            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16053                    callingPid, callingUid)
16054                    != PackageManager.PERMISSION_GRANTED) {
16055                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16056                        + callingPid + ", uid=" + callingUid
16057                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16058                Slog.w(TAG, msg);
16059                throw new SecurityException(msg);
16060            }
16061            if (requiredPermission != null) {
16062                Slog.w(TAG, "Can't broadcast sticky intent " + intent
16063                        + " and enforce permission " + requiredPermission);
16064                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16065            }
16066            if (intent.getComponent() != null) {
16067                throw new SecurityException(
16068                        "Sticky broadcasts can't target a specific component");
16069            }
16070            // We use userId directly here, since the "all" target is maintained
16071            // as a separate set of sticky broadcasts.
16072            if (userId != UserHandle.USER_ALL) {
16073                // But first, if this is not a broadcast to all users, then
16074                // make sure it doesn't conflict with an existing broadcast to
16075                // all users.
16076                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16077                        UserHandle.USER_ALL);
16078                if (stickies != null) {
16079                    ArrayList<Intent> list = stickies.get(intent.getAction());
16080                    if (list != null) {
16081                        int N = list.size();
16082                        int i;
16083                        for (i=0; i<N; i++) {
16084                            if (intent.filterEquals(list.get(i))) {
16085                                throw new IllegalArgumentException(
16086                                        "Sticky broadcast " + intent + " for user "
16087                                        + userId + " conflicts with existing global broadcast");
16088                            }
16089                        }
16090                    }
16091                }
16092            }
16093            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16094            if (stickies == null) {
16095                stickies = new ArrayMap<String, ArrayList<Intent>>();
16096                mStickyBroadcasts.put(userId, stickies);
16097            }
16098            ArrayList<Intent> list = stickies.get(intent.getAction());
16099            if (list == null) {
16100                list = new ArrayList<Intent>();
16101                stickies.put(intent.getAction(), list);
16102            }
16103            int N = list.size();
16104            int i;
16105            for (i=0; i<N; i++) {
16106                if (intent.filterEquals(list.get(i))) {
16107                    // This sticky already exists, replace it.
16108                    list.set(i, new Intent(intent));
16109                    break;
16110                }
16111            }
16112            if (i >= N) {
16113                list.add(new Intent(intent));
16114            }
16115        }
16116
16117        int[] users;
16118        if (userId == UserHandle.USER_ALL) {
16119            // Caller wants broadcast to go to all started users.
16120            users = mStartedUserArray;
16121        } else {
16122            // Caller wants broadcast to go to one specific user.
16123            users = new int[] {userId};
16124        }
16125
16126        // Figure out who all will receive this broadcast.
16127        List receivers = null;
16128        List<BroadcastFilter> registeredReceivers = null;
16129        // Need to resolve the intent to interested receivers...
16130        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16131                 == 0) {
16132            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16133        }
16134        if (intent.getComponent() == null) {
16135            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16136                // Query one target user at a time, excluding shell-restricted users
16137                UserManagerService ums = getUserManagerLocked();
16138                for (int i = 0; i < users.length; i++) {
16139                    if (ums.hasUserRestriction(
16140                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16141                        continue;
16142                    }
16143                    List<BroadcastFilter> registeredReceiversForUser =
16144                            mReceiverResolver.queryIntent(intent,
16145                                    resolvedType, false, users[i]);
16146                    if (registeredReceivers == null) {
16147                        registeredReceivers = registeredReceiversForUser;
16148                    } else if (registeredReceiversForUser != null) {
16149                        registeredReceivers.addAll(registeredReceiversForUser);
16150                    }
16151                }
16152            } else {
16153                registeredReceivers = mReceiverResolver.queryIntent(intent,
16154                        resolvedType, false, userId);
16155            }
16156        }
16157
16158        final boolean replacePending =
16159                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16160
16161        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
16162                + " replacePending=" + replacePending);
16163
16164        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16165        if (!ordered && NR > 0) {
16166            // If we are not serializing this broadcast, then send the
16167            // registered receivers separately so they don't wait for the
16168            // components to be launched.
16169            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16170            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16171                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16172                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16173                    ordered, sticky, false, userId);
16174            if (DEBUG_BROADCAST) Slog.v(
16175                    TAG, "Enqueueing parallel broadcast " + r);
16176            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16177            if (!replaced) {
16178                queue.enqueueParallelBroadcastLocked(r);
16179                queue.scheduleBroadcastsLocked();
16180            }
16181            registeredReceivers = null;
16182            NR = 0;
16183        }
16184
16185        // Merge into one list.
16186        int ir = 0;
16187        if (receivers != null) {
16188            // A special case for PACKAGE_ADDED: do not allow the package
16189            // being added to see this broadcast.  This prevents them from
16190            // using this as a back door to get run as soon as they are
16191            // installed.  Maybe in the future we want to have a special install
16192            // broadcast or such for apps, but we'd like to deliberately make
16193            // this decision.
16194            String skipPackages[] = null;
16195            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16196                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16197                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16198                Uri data = intent.getData();
16199                if (data != null) {
16200                    String pkgName = data.getSchemeSpecificPart();
16201                    if (pkgName != null) {
16202                        skipPackages = new String[] { pkgName };
16203                    }
16204                }
16205            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16206                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16207            }
16208            if (skipPackages != null && (skipPackages.length > 0)) {
16209                for (String skipPackage : skipPackages) {
16210                    if (skipPackage != null) {
16211                        int NT = receivers.size();
16212                        for (int it=0; it<NT; it++) {
16213                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16214                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16215                                receivers.remove(it);
16216                                it--;
16217                                NT--;
16218                            }
16219                        }
16220                    }
16221                }
16222            }
16223
16224            int NT = receivers != null ? receivers.size() : 0;
16225            int it = 0;
16226            ResolveInfo curt = null;
16227            BroadcastFilter curr = null;
16228            while (it < NT && ir < NR) {
16229                if (curt == null) {
16230                    curt = (ResolveInfo)receivers.get(it);
16231                }
16232                if (curr == null) {
16233                    curr = registeredReceivers.get(ir);
16234                }
16235                if (curr.getPriority() >= curt.priority) {
16236                    // Insert this broadcast record into the final list.
16237                    receivers.add(it, curr);
16238                    ir++;
16239                    curr = null;
16240                    it++;
16241                    NT++;
16242                } else {
16243                    // Skip to the next ResolveInfo in the final list.
16244                    it++;
16245                    curt = null;
16246                }
16247            }
16248        }
16249        while (ir < NR) {
16250            if (receivers == null) {
16251                receivers = new ArrayList();
16252            }
16253            receivers.add(registeredReceivers.get(ir));
16254            ir++;
16255        }
16256
16257        if ((receivers != null && receivers.size() > 0)
16258                || resultTo != null) {
16259            BroadcastQueue queue = broadcastQueueForIntent(intent);
16260            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16261                    callerPackage, callingPid, callingUid, resolvedType,
16262                    requiredPermission, appOp, receivers, resultTo, resultCode,
16263                    resultData, map, ordered, sticky, false, userId);
16264            if (DEBUG_BROADCAST) Slog.v(
16265                    TAG, "Enqueueing ordered broadcast " + r
16266                    + ": prev had " + queue.mOrderedBroadcasts.size());
16267            if (DEBUG_BROADCAST) {
16268                int seq = r.intent.getIntExtra("seq", -1);
16269                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16270            }
16271            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16272            if (!replaced) {
16273                queue.enqueueOrderedBroadcastLocked(r);
16274                queue.scheduleBroadcastsLocked();
16275            }
16276        }
16277
16278        return ActivityManager.BROADCAST_SUCCESS;
16279    }
16280
16281    final Intent verifyBroadcastLocked(Intent intent) {
16282        // Refuse possible leaked file descriptors
16283        if (intent != null && intent.hasFileDescriptors() == true) {
16284            throw new IllegalArgumentException("File descriptors passed in Intent");
16285        }
16286
16287        int flags = intent.getFlags();
16288
16289        if (!mProcessesReady) {
16290            // if the caller really truly claims to know what they're doing, go
16291            // ahead and allow the broadcast without launching any receivers
16292            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16293                intent = new Intent(intent);
16294                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16295            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16296                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16297                        + " before boot completion");
16298                throw new IllegalStateException("Cannot broadcast before boot completed");
16299            }
16300        }
16301
16302        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16303            throw new IllegalArgumentException(
16304                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16305        }
16306
16307        return intent;
16308    }
16309
16310    public final int broadcastIntent(IApplicationThread caller,
16311            Intent intent, String resolvedType, IIntentReceiver resultTo,
16312            int resultCode, String resultData, Bundle map,
16313            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16314        enforceNotIsolatedCaller("broadcastIntent");
16315        synchronized(this) {
16316            intent = verifyBroadcastLocked(intent);
16317
16318            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16319            final int callingPid = Binder.getCallingPid();
16320            final int callingUid = Binder.getCallingUid();
16321            final long origId = Binder.clearCallingIdentity();
16322            int res = broadcastIntentLocked(callerApp,
16323                    callerApp != null ? callerApp.info.packageName : null,
16324                    intent, resolvedType, resultTo,
16325                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16326                    callingPid, callingUid, userId);
16327            Binder.restoreCallingIdentity(origId);
16328            return res;
16329        }
16330    }
16331
16332    int broadcastIntentInPackage(String packageName, int uid,
16333            Intent intent, String resolvedType, IIntentReceiver resultTo,
16334            int resultCode, String resultData, Bundle map,
16335            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16336        synchronized(this) {
16337            intent = verifyBroadcastLocked(intent);
16338
16339            final long origId = Binder.clearCallingIdentity();
16340            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16341                    resultTo, resultCode, resultData, map, requiredPermission,
16342                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16343            Binder.restoreCallingIdentity(origId);
16344            return res;
16345        }
16346    }
16347
16348    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16349        // Refuse possible leaked file descriptors
16350        if (intent != null && intent.hasFileDescriptors() == true) {
16351            throw new IllegalArgumentException("File descriptors passed in Intent");
16352        }
16353
16354        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16355                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16356
16357        synchronized(this) {
16358            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16359                    != PackageManager.PERMISSION_GRANTED) {
16360                String msg = "Permission Denial: unbroadcastIntent() from pid="
16361                        + Binder.getCallingPid()
16362                        + ", uid=" + Binder.getCallingUid()
16363                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16364                Slog.w(TAG, msg);
16365                throw new SecurityException(msg);
16366            }
16367            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16368            if (stickies != null) {
16369                ArrayList<Intent> list = stickies.get(intent.getAction());
16370                if (list != null) {
16371                    int N = list.size();
16372                    int i;
16373                    for (i=0; i<N; i++) {
16374                        if (intent.filterEquals(list.get(i))) {
16375                            list.remove(i);
16376                            break;
16377                        }
16378                    }
16379                    if (list.size() <= 0) {
16380                        stickies.remove(intent.getAction());
16381                    }
16382                }
16383                if (stickies.size() <= 0) {
16384                    mStickyBroadcasts.remove(userId);
16385                }
16386            }
16387        }
16388    }
16389
16390    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16391            String resultData, Bundle resultExtras, boolean resultAbort) {
16392        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16393        if (r == null) {
16394            Slog.w(TAG, "finishReceiver called but not found on queue");
16395            return false;
16396        }
16397
16398        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16399    }
16400
16401    void backgroundServicesFinishedLocked(int userId) {
16402        for (BroadcastQueue queue : mBroadcastQueues) {
16403            queue.backgroundServicesFinishedLocked(userId);
16404        }
16405    }
16406
16407    public void finishReceiver(IBinder who, int resultCode, String resultData,
16408            Bundle resultExtras, boolean resultAbort) {
16409        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16410
16411        // Refuse possible leaked file descriptors
16412        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16413            throw new IllegalArgumentException("File descriptors passed in Bundle");
16414        }
16415
16416        final long origId = Binder.clearCallingIdentity();
16417        try {
16418            boolean doNext = false;
16419            BroadcastRecord r;
16420
16421            synchronized(this) {
16422                r = broadcastRecordForReceiverLocked(who);
16423                if (r != null) {
16424                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16425                        resultData, resultExtras, resultAbort, true);
16426                }
16427            }
16428
16429            if (doNext) {
16430                r.queue.processNextBroadcast(false);
16431            }
16432            trimApplications();
16433        } finally {
16434            Binder.restoreCallingIdentity(origId);
16435        }
16436    }
16437
16438    // =========================================================
16439    // INSTRUMENTATION
16440    // =========================================================
16441
16442    public boolean startInstrumentation(ComponentName className,
16443            String profileFile, int flags, Bundle arguments,
16444            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16445            int userId, String abiOverride) {
16446        enforceNotIsolatedCaller("startInstrumentation");
16447        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16448                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16449        // Refuse possible leaked file descriptors
16450        if (arguments != null && arguments.hasFileDescriptors()) {
16451            throw new IllegalArgumentException("File descriptors passed in Bundle");
16452        }
16453
16454        synchronized(this) {
16455            InstrumentationInfo ii = null;
16456            ApplicationInfo ai = null;
16457            try {
16458                ii = mContext.getPackageManager().getInstrumentationInfo(
16459                    className, STOCK_PM_FLAGS);
16460                ai = AppGlobals.getPackageManager().getApplicationInfo(
16461                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16462            } catch (PackageManager.NameNotFoundException e) {
16463            } catch (RemoteException e) {
16464            }
16465            if (ii == null) {
16466                reportStartInstrumentationFailure(watcher, className,
16467                        "Unable to find instrumentation info for: " + className);
16468                return false;
16469            }
16470            if (ai == null) {
16471                reportStartInstrumentationFailure(watcher, className,
16472                        "Unable to find instrumentation target package: " + ii.targetPackage);
16473                return false;
16474            }
16475
16476            int match = mContext.getPackageManager().checkSignatures(
16477                    ii.targetPackage, ii.packageName);
16478            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16479                String msg = "Permission Denial: starting instrumentation "
16480                        + className + " from pid="
16481                        + Binder.getCallingPid()
16482                        + ", uid=" + Binder.getCallingPid()
16483                        + " not allowed because package " + ii.packageName
16484                        + " does not have a signature matching the target "
16485                        + ii.targetPackage;
16486                reportStartInstrumentationFailure(watcher, className, msg);
16487                throw new SecurityException(msg);
16488            }
16489
16490            final long origId = Binder.clearCallingIdentity();
16491            // Instrumentation can kill and relaunch even persistent processes
16492            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16493                    "start instr");
16494            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16495            app.instrumentationClass = className;
16496            app.instrumentationInfo = ai;
16497            app.instrumentationProfileFile = profileFile;
16498            app.instrumentationArguments = arguments;
16499            app.instrumentationWatcher = watcher;
16500            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16501            app.instrumentationResultClass = className;
16502            Binder.restoreCallingIdentity(origId);
16503        }
16504
16505        return true;
16506    }
16507
16508    /**
16509     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16510     * error to the logs, but if somebody is watching, send the report there too.  This enables
16511     * the "am" command to report errors with more information.
16512     *
16513     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16514     * @param cn The component name of the instrumentation.
16515     * @param report The error report.
16516     */
16517    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16518            ComponentName cn, String report) {
16519        Slog.w(TAG, report);
16520        try {
16521            if (watcher != null) {
16522                Bundle results = new Bundle();
16523                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16524                results.putString("Error", report);
16525                watcher.instrumentationStatus(cn, -1, results);
16526            }
16527        } catch (RemoteException e) {
16528            Slog.w(TAG, e);
16529        }
16530    }
16531
16532    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16533        if (app.instrumentationWatcher != null) {
16534            try {
16535                // NOTE:  IInstrumentationWatcher *must* be oneway here
16536                app.instrumentationWatcher.instrumentationFinished(
16537                    app.instrumentationClass,
16538                    resultCode,
16539                    results);
16540            } catch (RemoteException e) {
16541            }
16542        }
16543        if (app.instrumentationUiAutomationConnection != null) {
16544            try {
16545                app.instrumentationUiAutomationConnection.shutdown();
16546            } catch (RemoteException re) {
16547                /* ignore */
16548            }
16549            // Only a UiAutomation can set this flag and now that
16550            // it is finished we make sure it is reset to its default.
16551            mUserIsMonkey = false;
16552        }
16553        app.instrumentationWatcher = null;
16554        app.instrumentationUiAutomationConnection = null;
16555        app.instrumentationClass = null;
16556        app.instrumentationInfo = null;
16557        app.instrumentationProfileFile = null;
16558        app.instrumentationArguments = null;
16559
16560        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16561                "finished inst");
16562    }
16563
16564    public void finishInstrumentation(IApplicationThread target,
16565            int resultCode, Bundle results) {
16566        int userId = UserHandle.getCallingUserId();
16567        // Refuse possible leaked file descriptors
16568        if (results != null && results.hasFileDescriptors()) {
16569            throw new IllegalArgumentException("File descriptors passed in Intent");
16570        }
16571
16572        synchronized(this) {
16573            ProcessRecord app = getRecordForAppLocked(target);
16574            if (app == null) {
16575                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16576                return;
16577            }
16578            final long origId = Binder.clearCallingIdentity();
16579            finishInstrumentationLocked(app, resultCode, results);
16580            Binder.restoreCallingIdentity(origId);
16581        }
16582    }
16583
16584    // =========================================================
16585    // CONFIGURATION
16586    // =========================================================
16587
16588    public ConfigurationInfo getDeviceConfigurationInfo() {
16589        ConfigurationInfo config = new ConfigurationInfo();
16590        synchronized (this) {
16591            config.reqTouchScreen = mConfiguration.touchscreen;
16592            config.reqKeyboardType = mConfiguration.keyboard;
16593            config.reqNavigation = mConfiguration.navigation;
16594            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16595                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16596                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16597            }
16598            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16599                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16600                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16601            }
16602            config.reqGlEsVersion = GL_ES_VERSION;
16603        }
16604        return config;
16605    }
16606
16607    ActivityStack getFocusedStack() {
16608        return mStackSupervisor.getFocusedStack();
16609    }
16610
16611    public Configuration getConfiguration() {
16612        Configuration ci;
16613        synchronized(this) {
16614            ci = new Configuration(mConfiguration);
16615            ci.userSetLocale = false;
16616        }
16617        return ci;
16618    }
16619
16620    public void updatePersistentConfiguration(Configuration values) {
16621        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16622                "updateConfiguration()");
16623        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16624                "updateConfiguration()");
16625        if (values == null) {
16626            throw new NullPointerException("Configuration must not be null");
16627        }
16628
16629        synchronized(this) {
16630            final long origId = Binder.clearCallingIdentity();
16631            updateConfigurationLocked(values, null, true, false);
16632            Binder.restoreCallingIdentity(origId);
16633        }
16634    }
16635
16636    public void updateConfiguration(Configuration values) {
16637        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16638                "updateConfiguration()");
16639
16640        synchronized(this) {
16641            if (values == null && mWindowManager != null) {
16642                // sentinel: fetch the current configuration from the window manager
16643                values = mWindowManager.computeNewConfiguration();
16644            }
16645
16646            if (mWindowManager != null) {
16647                mProcessList.applyDisplaySize(mWindowManager);
16648            }
16649
16650            final long origId = Binder.clearCallingIdentity();
16651            if (values != null) {
16652                Settings.System.clearConfiguration(values);
16653            }
16654            updateConfigurationLocked(values, null, false, false);
16655            Binder.restoreCallingIdentity(origId);
16656        }
16657    }
16658
16659    /**
16660     * Do either or both things: (1) change the current configuration, and (2)
16661     * make sure the given activity is running with the (now) current
16662     * configuration.  Returns true if the activity has been left running, or
16663     * false if <var>starting</var> is being destroyed to match the new
16664     * configuration.
16665     * @param persistent TODO
16666     */
16667    boolean updateConfigurationLocked(Configuration values,
16668            ActivityRecord starting, boolean persistent, boolean initLocale) {
16669        int changes = 0;
16670
16671        if (values != null) {
16672            Configuration newConfig = new Configuration(mConfiguration);
16673            changes = newConfig.updateFrom(values);
16674            if (changes != 0) {
16675                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16676                    Slog.i(TAG, "Updating configuration to: " + values);
16677                }
16678
16679                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16680
16681                if (values.locale != null && !initLocale) {
16682                    saveLocaleLocked(values.locale,
16683                                     !values.locale.equals(mConfiguration.locale),
16684                                     values.userSetLocale);
16685                }
16686
16687                mConfigurationSeq++;
16688                if (mConfigurationSeq <= 0) {
16689                    mConfigurationSeq = 1;
16690                }
16691                newConfig.seq = mConfigurationSeq;
16692                mConfiguration = newConfig;
16693                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16694                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16695                //mUsageStatsService.noteStartConfig(newConfig);
16696
16697                final Configuration configCopy = new Configuration(mConfiguration);
16698
16699                // TODO: If our config changes, should we auto dismiss any currently
16700                // showing dialogs?
16701                mShowDialogs = shouldShowDialogs(newConfig);
16702
16703                AttributeCache ac = AttributeCache.instance();
16704                if (ac != null) {
16705                    ac.updateConfiguration(configCopy);
16706                }
16707
16708                // Make sure all resources in our process are updated
16709                // right now, so that anyone who is going to retrieve
16710                // resource values after we return will be sure to get
16711                // the new ones.  This is especially important during
16712                // boot, where the first config change needs to guarantee
16713                // all resources have that config before following boot
16714                // code is executed.
16715                mSystemThread.applyConfigurationToResources(configCopy);
16716
16717                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16718                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16719                    msg.obj = new Configuration(configCopy);
16720                    mHandler.sendMessage(msg);
16721                }
16722
16723                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16724                    ProcessRecord app = mLruProcesses.get(i);
16725                    try {
16726                        if (app.thread != null) {
16727                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16728                                    + app.processName + " new config " + mConfiguration);
16729                            app.thread.scheduleConfigurationChanged(configCopy);
16730                        }
16731                    } catch (Exception e) {
16732                    }
16733                }
16734                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16735                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16736                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16737                        | Intent.FLAG_RECEIVER_FOREGROUND);
16738                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16739                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16740                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16741                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16742                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16743                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16744                    broadcastIntentLocked(null, null, intent,
16745                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16746                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16747                }
16748            }
16749        }
16750
16751        boolean kept = true;
16752        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16753        // mainStack is null during startup.
16754        if (mainStack != null) {
16755            if (changes != 0 && starting == null) {
16756                // If the configuration changed, and the caller is not already
16757                // in the process of starting an activity, then find the top
16758                // activity to check if its configuration needs to change.
16759                starting = mainStack.topRunningActivityLocked(null);
16760            }
16761
16762            if (starting != null) {
16763                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16764                // And we need to make sure at this point that all other activities
16765                // are made visible with the correct configuration.
16766                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16767            }
16768        }
16769
16770        if (values != null && mWindowManager != null) {
16771            mWindowManager.setNewConfiguration(mConfiguration);
16772        }
16773
16774        return kept;
16775    }
16776
16777    /**
16778     * Decide based on the configuration whether we should shouw the ANR,
16779     * crash, etc dialogs.  The idea is that if there is no affordnace to
16780     * press the on-screen buttons, we shouldn't show the dialog.
16781     *
16782     * A thought: SystemUI might also want to get told about this, the Power
16783     * dialog / global actions also might want different behaviors.
16784     */
16785    private static final boolean shouldShowDialogs(Configuration config) {
16786        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16787                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16788    }
16789
16790    /**
16791     * Save the locale.  You must be inside a synchronized (this) block.
16792     */
16793    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16794        if(isDiff) {
16795            SystemProperties.set("user.language", l.getLanguage());
16796            SystemProperties.set("user.region", l.getCountry());
16797        }
16798
16799        if(isPersist) {
16800            SystemProperties.set("persist.sys.language", l.getLanguage());
16801            SystemProperties.set("persist.sys.country", l.getCountry());
16802            SystemProperties.set("persist.sys.localevar", l.getVariant());
16803
16804            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16805        }
16806    }
16807
16808    @Override
16809    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16810        synchronized (this) {
16811            ActivityRecord srec = ActivityRecord.forToken(token);
16812            if (srec.task != null && srec.task.stack != null) {
16813                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16814            }
16815        }
16816        return false;
16817    }
16818
16819    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16820            Intent resultData) {
16821
16822        synchronized (this) {
16823            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16824            if (stack != null) {
16825                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16826            }
16827            return false;
16828        }
16829    }
16830
16831    public int getLaunchedFromUid(IBinder activityToken) {
16832        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16833        if (srec == null) {
16834            return -1;
16835        }
16836        return srec.launchedFromUid;
16837    }
16838
16839    public String getLaunchedFromPackage(IBinder activityToken) {
16840        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16841        if (srec == null) {
16842            return null;
16843        }
16844        return srec.launchedFromPackage;
16845    }
16846
16847    // =========================================================
16848    // LIFETIME MANAGEMENT
16849    // =========================================================
16850
16851    // Returns which broadcast queue the app is the current [or imminent] receiver
16852    // on, or 'null' if the app is not an active broadcast recipient.
16853    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16854        BroadcastRecord r = app.curReceiver;
16855        if (r != null) {
16856            return r.queue;
16857        }
16858
16859        // It's not the current receiver, but it might be starting up to become one
16860        synchronized (this) {
16861            for (BroadcastQueue queue : mBroadcastQueues) {
16862                r = queue.mPendingBroadcast;
16863                if (r != null && r.curApp == app) {
16864                    // found it; report which queue it's in
16865                    return queue;
16866                }
16867            }
16868        }
16869
16870        return null;
16871    }
16872
16873    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16874            ComponentName targetComponent, String targetProcess) {
16875        if (!mTrackingAssociations) {
16876            return null;
16877        }
16878        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16879                = mAssociations.get(targetUid);
16880        if (components == null) {
16881            components = new ArrayMap<>();
16882            mAssociations.put(targetUid, components);
16883        }
16884        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16885        if (sourceUids == null) {
16886            sourceUids = new SparseArray<>();
16887            components.put(targetComponent, sourceUids);
16888        }
16889        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16890        if (sourceProcesses == null) {
16891            sourceProcesses = new ArrayMap<>();
16892            sourceUids.put(sourceUid, sourceProcesses);
16893        }
16894        Association ass = sourceProcesses.get(sourceProcess);
16895        if (ass == null) {
16896            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
16897                    targetProcess);
16898            sourceProcesses.put(sourceProcess, ass);
16899        }
16900        ass.mCount++;
16901        ass.mNesting++;
16902        if (ass.mNesting == 1) {
16903            ass.mStartTime = SystemClock.uptimeMillis();
16904        }
16905        return ass;
16906    }
16907
16908    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16909            ComponentName targetComponent) {
16910        if (!mTrackingAssociations) {
16911            return;
16912        }
16913        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16914                = mAssociations.get(targetUid);
16915        if (components == null) {
16916            return;
16917        }
16918        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16919        if (sourceUids == null) {
16920            return;
16921        }
16922        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16923        if (sourceProcesses == null) {
16924            return;
16925        }
16926        Association ass = sourceProcesses.get(sourceProcess);
16927        if (ass == null || ass.mNesting <= 0) {
16928            return;
16929        }
16930        ass.mNesting--;
16931        if (ass.mNesting == 0) {
16932            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
16933        }
16934    }
16935
16936    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16937            boolean doingAll, long now) {
16938        if (mAdjSeq == app.adjSeq) {
16939            // This adjustment has already been computed.
16940            return app.curRawAdj;
16941        }
16942
16943        if (app.thread == null) {
16944            app.adjSeq = mAdjSeq;
16945            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16946            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16947            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16948        }
16949
16950        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16951        app.adjSource = null;
16952        app.adjTarget = null;
16953        app.empty = false;
16954        app.cached = false;
16955
16956        final int activitiesSize = app.activities.size();
16957
16958        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16959            // The max adjustment doesn't allow this app to be anything
16960            // below foreground, so it is not worth doing work for it.
16961            app.adjType = "fixed";
16962            app.adjSeq = mAdjSeq;
16963            app.curRawAdj = app.maxAdj;
16964            app.foregroundActivities = false;
16965            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16966            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16967            // System processes can do UI, and when they do we want to have
16968            // them trim their memory after the user leaves the UI.  To
16969            // facilitate this, here we need to determine whether or not it
16970            // is currently showing UI.
16971            app.systemNoUi = true;
16972            if (app == TOP_APP) {
16973                app.systemNoUi = false;
16974            } else if (activitiesSize > 0) {
16975                for (int j = 0; j < activitiesSize; j++) {
16976                    final ActivityRecord r = app.activities.get(j);
16977                    if (r.visible) {
16978                        app.systemNoUi = false;
16979                    }
16980                }
16981            }
16982            if (!app.systemNoUi) {
16983                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16984            }
16985            return (app.curAdj=app.maxAdj);
16986        }
16987
16988        app.systemNoUi = false;
16989
16990        // Determine the importance of the process, starting with most
16991        // important to least, and assign an appropriate OOM adjustment.
16992        int adj;
16993        int schedGroup;
16994        int procState;
16995        boolean foregroundActivities = false;
16996        BroadcastQueue queue;
16997        if (app == TOP_APP) {
16998            // The last app on the list is the foreground app.
16999            adj = ProcessList.FOREGROUND_APP_ADJ;
17000            schedGroup = Process.THREAD_GROUP_DEFAULT;
17001            app.adjType = "top-activity";
17002            foregroundActivities = true;
17003            procState = ActivityManager.PROCESS_STATE_TOP;
17004        } else if (app.instrumentationClass != null) {
17005            // Don't want to kill running instrumentation.
17006            adj = ProcessList.FOREGROUND_APP_ADJ;
17007            schedGroup = Process.THREAD_GROUP_DEFAULT;
17008            app.adjType = "instrumentation";
17009            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17010        } else if ((queue = isReceivingBroadcast(app)) != null) {
17011            // An app that is currently receiving a broadcast also
17012            // counts as being in the foreground for OOM killer purposes.
17013            // It's placed in a sched group based on the nature of the
17014            // broadcast as reflected by which queue it's active in.
17015            adj = ProcessList.FOREGROUND_APP_ADJ;
17016            schedGroup = (queue == mFgBroadcastQueue)
17017                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17018            app.adjType = "broadcast";
17019            procState = ActivityManager.PROCESS_STATE_RECEIVER;
17020        } else if (app.executingServices.size() > 0) {
17021            // An app that is currently executing a service callback also
17022            // counts as being in the foreground.
17023            adj = ProcessList.FOREGROUND_APP_ADJ;
17024            schedGroup = app.execServicesFg ?
17025                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17026            app.adjType = "exec-service";
17027            procState = ActivityManager.PROCESS_STATE_SERVICE;
17028            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17029        } else {
17030            // As far as we know the process is empty.  We may change our mind later.
17031            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17032            // At this point we don't actually know the adjustment.  Use the cached adj
17033            // value that the caller wants us to.
17034            adj = cachedAdj;
17035            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17036            app.cached = true;
17037            app.empty = true;
17038            app.adjType = "cch-empty";
17039        }
17040
17041        // Examine all activities if not already foreground.
17042        if (!foregroundActivities && activitiesSize > 0) {
17043            for (int j = 0; j < activitiesSize; j++) {
17044                final ActivityRecord r = app.activities.get(j);
17045                if (r.app != app) {
17046                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17047                            + app + "?!?");
17048                    continue;
17049                }
17050                if (r.visible) {
17051                    // App has a visible activity; only upgrade adjustment.
17052                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17053                        adj = ProcessList.VISIBLE_APP_ADJ;
17054                        app.adjType = "visible";
17055                    }
17056                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
17057                        procState = ActivityManager.PROCESS_STATE_TOP;
17058                    }
17059                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17060                    app.cached = false;
17061                    app.empty = false;
17062                    foregroundActivities = true;
17063                    break;
17064                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17065                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17066                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17067                        app.adjType = "pausing";
17068                    }
17069                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
17070                        procState = ActivityManager.PROCESS_STATE_TOP;
17071                    }
17072                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17073                    app.cached = false;
17074                    app.empty = false;
17075                    foregroundActivities = true;
17076                } else if (r.state == ActivityState.STOPPING) {
17077                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17078                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17079                        app.adjType = "stopping";
17080                    }
17081                    // For the process state, we will at this point consider the
17082                    // process to be cached.  It will be cached either as an activity
17083                    // or empty depending on whether the activity is finishing.  We do
17084                    // this so that we can treat the process as cached for purposes of
17085                    // memory trimming (determing current memory level, trim command to
17086                    // send to process) since there can be an arbitrary number of stopping
17087                    // processes and they should soon all go into the cached state.
17088                    if (!r.finishing) {
17089                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17090                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17091                        }
17092                    }
17093                    app.cached = false;
17094                    app.empty = false;
17095                    foregroundActivities = true;
17096                } else {
17097                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17098                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17099                        app.adjType = "cch-act";
17100                    }
17101                }
17102            }
17103        }
17104
17105        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17106            if (app.foregroundServices) {
17107                // The user is aware of this app, so make it visible.
17108                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17109                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17110                app.cached = false;
17111                app.adjType = "fg-service";
17112                schedGroup = Process.THREAD_GROUP_DEFAULT;
17113            } else if (app.forcingToForeground != null) {
17114                // The user is aware of this app, so make it visible.
17115                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17116                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17117                app.cached = false;
17118                app.adjType = "force-fg";
17119                app.adjSource = app.forcingToForeground;
17120                schedGroup = Process.THREAD_GROUP_DEFAULT;
17121            }
17122        }
17123
17124        if (app == mHeavyWeightProcess) {
17125            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17126                // We don't want to kill the current heavy-weight process.
17127                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17128                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17129                app.cached = false;
17130                app.adjType = "heavy";
17131            }
17132            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17133                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17134            }
17135        }
17136
17137        if (app == mHomeProcess) {
17138            if (adj > ProcessList.HOME_APP_ADJ) {
17139                // This process is hosting what we currently consider to be the
17140                // home app, so we don't want to let it go into the background.
17141                adj = ProcessList.HOME_APP_ADJ;
17142                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17143                app.cached = false;
17144                app.adjType = "home";
17145            }
17146            if (procState > ActivityManager.PROCESS_STATE_HOME) {
17147                procState = ActivityManager.PROCESS_STATE_HOME;
17148            }
17149        }
17150
17151        if (app == mPreviousProcess && app.activities.size() > 0) {
17152            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17153                // This was the previous process that showed UI to the user.
17154                // We want to try to keep it around more aggressively, to give
17155                // a good experience around switching between two apps.
17156                adj = ProcessList.PREVIOUS_APP_ADJ;
17157                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17158                app.cached = false;
17159                app.adjType = "previous";
17160            }
17161            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17162                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17163            }
17164        }
17165
17166        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17167                + " reason=" + app.adjType);
17168
17169        // By default, we use the computed adjustment.  It may be changed if
17170        // there are applications dependent on our services or providers, but
17171        // this gives us a baseline and makes sure we don't get into an
17172        // infinite recursion.
17173        app.adjSeq = mAdjSeq;
17174        app.curRawAdj = adj;
17175        app.hasStartedServices = false;
17176
17177        if (mBackupTarget != null && app == mBackupTarget.app) {
17178            // If possible we want to avoid killing apps while they're being backed up
17179            if (adj > ProcessList.BACKUP_APP_ADJ) {
17180                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
17181                adj = ProcessList.BACKUP_APP_ADJ;
17182                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17183                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17184                }
17185                app.adjType = "backup";
17186                app.cached = false;
17187            }
17188            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17189                procState = ActivityManager.PROCESS_STATE_BACKUP;
17190            }
17191        }
17192
17193        boolean mayBeTop = false;
17194
17195        for (int is = app.services.size()-1;
17196                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17197                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17198                        || procState > ActivityManager.PROCESS_STATE_TOP);
17199                is--) {
17200            ServiceRecord s = app.services.valueAt(is);
17201            if (s.startRequested) {
17202                app.hasStartedServices = true;
17203                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17204                    procState = ActivityManager.PROCESS_STATE_SERVICE;
17205                }
17206                if (app.hasShownUi && app != mHomeProcess) {
17207                    // If this process has shown some UI, let it immediately
17208                    // go to the LRU list because it may be pretty heavy with
17209                    // UI stuff.  We'll tag it with a label just to help
17210                    // debug and understand what is going on.
17211                    if (adj > ProcessList.SERVICE_ADJ) {
17212                        app.adjType = "cch-started-ui-services";
17213                    }
17214                } else {
17215                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17216                        // This service has seen some activity within
17217                        // recent memory, so we will keep its process ahead
17218                        // of the background processes.
17219                        if (adj > ProcessList.SERVICE_ADJ) {
17220                            adj = ProcessList.SERVICE_ADJ;
17221                            app.adjType = "started-services";
17222                            app.cached = false;
17223                        }
17224                    }
17225                    // If we have let the service slide into the background
17226                    // state, still have some text describing what it is doing
17227                    // even though the service no longer has an impact.
17228                    if (adj > ProcessList.SERVICE_ADJ) {
17229                        app.adjType = "cch-started-services";
17230                    }
17231                }
17232            }
17233            for (int conni = s.connections.size()-1;
17234                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17235                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17236                            || procState > ActivityManager.PROCESS_STATE_TOP);
17237                    conni--) {
17238                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17239                for (int i = 0;
17240                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17241                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17242                                || procState > ActivityManager.PROCESS_STATE_TOP);
17243                        i++) {
17244                    // XXX should compute this based on the max of
17245                    // all connected clients.
17246                    ConnectionRecord cr = clist.get(i);
17247                    if (cr.binding.client == app) {
17248                        // Binding to ourself is not interesting.
17249                        continue;
17250                    }
17251                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17252                        ProcessRecord client = cr.binding.client;
17253                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17254                                TOP_APP, doingAll, now);
17255                        int clientProcState = client.curProcState;
17256                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17257                            // If the other app is cached for any reason, for purposes here
17258                            // we are going to consider it empty.  The specific cached state
17259                            // doesn't propagate except under certain conditions.
17260                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17261                        }
17262                        String adjType = null;
17263                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17264                            // Not doing bind OOM management, so treat
17265                            // this guy more like a started service.
17266                            if (app.hasShownUi && app != mHomeProcess) {
17267                                // If this process has shown some UI, let it immediately
17268                                // go to the LRU list because it may be pretty heavy with
17269                                // UI stuff.  We'll tag it with a label just to help
17270                                // debug and understand what is going on.
17271                                if (adj > clientAdj) {
17272                                    adjType = "cch-bound-ui-services";
17273                                }
17274                                app.cached = false;
17275                                clientAdj = adj;
17276                                clientProcState = procState;
17277                            } else {
17278                                if (now >= (s.lastActivity
17279                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17280                                    // This service has not seen activity within
17281                                    // recent memory, so allow it to drop to the
17282                                    // LRU list if there is no other reason to keep
17283                                    // it around.  We'll also tag it with a label just
17284                                    // to help debug and undertand what is going on.
17285                                    if (adj > clientAdj) {
17286                                        adjType = "cch-bound-services";
17287                                    }
17288                                    clientAdj = adj;
17289                                }
17290                            }
17291                        }
17292                        if (adj > clientAdj) {
17293                            // If this process has recently shown UI, and
17294                            // the process that is binding to it is less
17295                            // important than being visible, then we don't
17296                            // care about the binding as much as we care
17297                            // about letting this process get into the LRU
17298                            // list to be killed and restarted if needed for
17299                            // memory.
17300                            if (app.hasShownUi && app != mHomeProcess
17301                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17302                                adjType = "cch-bound-ui-services";
17303                            } else {
17304                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17305                                        |Context.BIND_IMPORTANT)) != 0) {
17306                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17307                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17308                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17309                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17310                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17311                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17312                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17313                                    adj = clientAdj;
17314                                } else {
17315                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17316                                        adj = ProcessList.VISIBLE_APP_ADJ;
17317                                    }
17318                                }
17319                                if (!client.cached) {
17320                                    app.cached = false;
17321                                }
17322                                adjType = "service";
17323                            }
17324                        }
17325                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17326                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17327                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17328                            }
17329                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17330                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17331                                    // Special handling of clients who are in the top state.
17332                                    // We *may* want to consider this process to be in the
17333                                    // top state as well, but only if there is not another
17334                                    // reason for it to be running.  Being on the top is a
17335                                    // special state, meaning you are specifically running
17336                                    // for the current top app.  If the process is already
17337                                    // running in the background for some other reason, it
17338                                    // is more important to continue considering it to be
17339                                    // in the background state.
17340                                    mayBeTop = true;
17341                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17342                                } else {
17343                                    // Special handling for above-top states (persistent
17344                                    // processes).  These should not bring the current process
17345                                    // into the top state, since they are not on top.  Instead
17346                                    // give them the best state after that.
17347                                    clientProcState =
17348                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17349                                }
17350                            }
17351                        } else {
17352                            if (clientProcState <
17353                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17354                                clientProcState =
17355                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17356                            }
17357                        }
17358                        if (procState > clientProcState) {
17359                            procState = clientProcState;
17360                        }
17361                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17362                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17363                            app.pendingUiClean = true;
17364                        }
17365                        if (adjType != null) {
17366                            app.adjType = adjType;
17367                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17368                                    .REASON_SERVICE_IN_USE;
17369                            app.adjSource = cr.binding.client;
17370                            app.adjSourceProcState = clientProcState;
17371                            app.adjTarget = s.name;
17372                        }
17373                    }
17374                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17375                        app.treatLikeActivity = true;
17376                    }
17377                    final ActivityRecord a = cr.activity;
17378                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17379                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17380                                (a.visible || a.state == ActivityState.RESUMED
17381                                 || a.state == ActivityState.PAUSING)) {
17382                            adj = ProcessList.FOREGROUND_APP_ADJ;
17383                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17384                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17385                            }
17386                            app.cached = false;
17387                            app.adjType = "service";
17388                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17389                                    .REASON_SERVICE_IN_USE;
17390                            app.adjSource = a;
17391                            app.adjSourceProcState = procState;
17392                            app.adjTarget = s.name;
17393                        }
17394                    }
17395                }
17396            }
17397        }
17398
17399        for (int provi = app.pubProviders.size()-1;
17400                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17401                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17402                        || procState > ActivityManager.PROCESS_STATE_TOP);
17403                provi--) {
17404            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17405            for (int i = cpr.connections.size()-1;
17406                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17407                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17408                            || procState > ActivityManager.PROCESS_STATE_TOP);
17409                    i--) {
17410                ContentProviderConnection conn = cpr.connections.get(i);
17411                ProcessRecord client = conn.client;
17412                if (client == app) {
17413                    // Being our own client is not interesting.
17414                    continue;
17415                }
17416                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17417                int clientProcState = client.curProcState;
17418                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17419                    // If the other app is cached for any reason, for purposes here
17420                    // we are going to consider it empty.
17421                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17422                }
17423                if (adj > clientAdj) {
17424                    if (app.hasShownUi && app != mHomeProcess
17425                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17426                        app.adjType = "cch-ui-provider";
17427                    } else {
17428                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17429                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17430                        app.adjType = "provider";
17431                    }
17432                    app.cached &= client.cached;
17433                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17434                            .REASON_PROVIDER_IN_USE;
17435                    app.adjSource = client;
17436                    app.adjSourceProcState = clientProcState;
17437                    app.adjTarget = cpr.name;
17438                }
17439                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17440                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17441                        // Special handling of clients who are in the top state.
17442                        // We *may* want to consider this process to be in the
17443                        // top state as well, but only if there is not another
17444                        // reason for it to be running.  Being on the top is a
17445                        // special state, meaning you are specifically running
17446                        // for the current top app.  If the process is already
17447                        // running in the background for some other reason, it
17448                        // is more important to continue considering it to be
17449                        // in the background state.
17450                        mayBeTop = true;
17451                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17452                    } else {
17453                        // Special handling for above-top states (persistent
17454                        // processes).  These should not bring the current process
17455                        // into the top state, since they are not on top.  Instead
17456                        // give them the best state after that.
17457                        clientProcState =
17458                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17459                    }
17460                }
17461                if (procState > clientProcState) {
17462                    procState = clientProcState;
17463                }
17464                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17465                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17466                }
17467            }
17468            // If the provider has external (non-framework) process
17469            // dependencies, ensure that its adjustment is at least
17470            // FOREGROUND_APP_ADJ.
17471            if (cpr.hasExternalProcessHandles()) {
17472                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17473                    adj = ProcessList.FOREGROUND_APP_ADJ;
17474                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17475                    app.cached = false;
17476                    app.adjType = "provider";
17477                    app.adjTarget = cpr.name;
17478                }
17479                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17480                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17481                }
17482            }
17483        }
17484
17485        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17486            // A client of one of our services or providers is in the top state.  We
17487            // *may* want to be in the top state, but not if we are already running in
17488            // the background for some other reason.  For the decision here, we are going
17489            // to pick out a few specific states that we want to remain in when a client
17490            // is top (states that tend to be longer-term) and otherwise allow it to go
17491            // to the top state.
17492            switch (procState) {
17493                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17494                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17495                case ActivityManager.PROCESS_STATE_SERVICE:
17496                    // These all are longer-term states, so pull them up to the top
17497                    // of the background states, but not all the way to the top state.
17498                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17499                    break;
17500                default:
17501                    // Otherwise, top is a better choice, so take it.
17502                    procState = ActivityManager.PROCESS_STATE_TOP;
17503                    break;
17504            }
17505        }
17506
17507        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17508            if (app.hasClientActivities) {
17509                // This is a cached process, but with client activities.  Mark it so.
17510                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17511                app.adjType = "cch-client-act";
17512            } else if (app.treatLikeActivity) {
17513                // This is a cached process, but somebody wants us to treat it like it has
17514                // an activity, okay!
17515                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17516                app.adjType = "cch-as-act";
17517            }
17518        }
17519
17520        if (adj == ProcessList.SERVICE_ADJ) {
17521            if (doingAll) {
17522                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17523                mNewNumServiceProcs++;
17524                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17525                if (!app.serviceb) {
17526                    // This service isn't far enough down on the LRU list to
17527                    // normally be a B service, but if we are low on RAM and it
17528                    // is large we want to force it down since we would prefer to
17529                    // keep launcher over it.
17530                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17531                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17532                        app.serviceHighRam = true;
17533                        app.serviceb = true;
17534                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17535                    } else {
17536                        mNewNumAServiceProcs++;
17537                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17538                    }
17539                } else {
17540                    app.serviceHighRam = false;
17541                }
17542            }
17543            if (app.serviceb) {
17544                adj = ProcessList.SERVICE_B_ADJ;
17545            }
17546        }
17547
17548        app.curRawAdj = adj;
17549
17550        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17551        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17552        if (adj > app.maxAdj) {
17553            adj = app.maxAdj;
17554            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17555                schedGroup = Process.THREAD_GROUP_DEFAULT;
17556            }
17557        }
17558
17559        // Do final modification to adj.  Everything we do between here and applying
17560        // the final setAdj must be done in this function, because we will also use
17561        // it when computing the final cached adj later.  Note that we don't need to
17562        // worry about this for max adj above, since max adj will always be used to
17563        // keep it out of the cached vaues.
17564        app.curAdj = app.modifyRawOomAdj(adj);
17565        app.curSchedGroup = schedGroup;
17566        app.curProcState = procState;
17567        app.foregroundActivities = foregroundActivities;
17568
17569        return app.curRawAdj;
17570    }
17571
17572    /**
17573     * Record new PSS sample for a process.
17574     */
17575    void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17576        proc.lastPssTime = now;
17577        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17578        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17579                + ": " + pss + " lastPss=" + proc.lastPss
17580                + " state=" + ProcessList.makeProcStateString(procState));
17581        if (proc.initialIdlePss == 0) {
17582            proc.initialIdlePss = pss;
17583        }
17584        proc.lastPss = pss;
17585        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17586            proc.lastCachedPss = pss;
17587        }
17588    }
17589
17590    /**
17591     * Schedule PSS collection of a process.
17592     */
17593    void requestPssLocked(ProcessRecord proc, int procState) {
17594        if (mPendingPssProcesses.contains(proc)) {
17595            return;
17596        }
17597        if (mPendingPssProcesses.size() == 0) {
17598            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17599        }
17600        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17601        proc.pssProcState = procState;
17602        mPendingPssProcesses.add(proc);
17603    }
17604
17605    /**
17606     * Schedule PSS collection of all processes.
17607     */
17608    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17609        if (!always) {
17610            if (now < (mLastFullPssTime +
17611                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17612                return;
17613            }
17614        }
17615        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17616        mLastFullPssTime = now;
17617        mFullPssPending = true;
17618        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17619        mPendingPssProcesses.clear();
17620        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17621            ProcessRecord app = mLruProcesses.get(i);
17622            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17623                app.pssProcState = app.setProcState;
17624                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17625                        mTestPssMode, isSleeping(), now);
17626                mPendingPssProcesses.add(app);
17627            }
17628        }
17629        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17630    }
17631
17632    public void setTestPssMode(boolean enabled) {
17633        synchronized (this) {
17634            mTestPssMode = enabled;
17635            if (enabled) {
17636                // Whenever we enable the mode, we want to take a snapshot all of current
17637                // process mem use.
17638                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17639            }
17640        }
17641    }
17642
17643    /**
17644     * Ask a given process to GC right now.
17645     */
17646    final void performAppGcLocked(ProcessRecord app) {
17647        try {
17648            app.lastRequestedGc = SystemClock.uptimeMillis();
17649            if (app.thread != null) {
17650                if (app.reportLowMemory) {
17651                    app.reportLowMemory = false;
17652                    app.thread.scheduleLowMemory();
17653                } else {
17654                    app.thread.processInBackground();
17655                }
17656            }
17657        } catch (Exception e) {
17658            // whatever.
17659        }
17660    }
17661
17662    /**
17663     * Returns true if things are idle enough to perform GCs.
17664     */
17665    private final boolean canGcNowLocked() {
17666        boolean processingBroadcasts = false;
17667        for (BroadcastQueue q : mBroadcastQueues) {
17668            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17669                processingBroadcasts = true;
17670            }
17671        }
17672        return !processingBroadcasts
17673                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17674    }
17675
17676    /**
17677     * Perform GCs on all processes that are waiting for it, but only
17678     * if things are idle.
17679     */
17680    final void performAppGcsLocked() {
17681        final int N = mProcessesToGc.size();
17682        if (N <= 0) {
17683            return;
17684        }
17685        if (canGcNowLocked()) {
17686            while (mProcessesToGc.size() > 0) {
17687                ProcessRecord proc = mProcessesToGc.remove(0);
17688                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17689                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17690                            <= SystemClock.uptimeMillis()) {
17691                        // To avoid spamming the system, we will GC processes one
17692                        // at a time, waiting a few seconds between each.
17693                        performAppGcLocked(proc);
17694                        scheduleAppGcsLocked();
17695                        return;
17696                    } else {
17697                        // It hasn't been long enough since we last GCed this
17698                        // process...  put it in the list to wait for its time.
17699                        addProcessToGcListLocked(proc);
17700                        break;
17701                    }
17702                }
17703            }
17704
17705            scheduleAppGcsLocked();
17706        }
17707    }
17708
17709    /**
17710     * If all looks good, perform GCs on all processes waiting for them.
17711     */
17712    final void performAppGcsIfAppropriateLocked() {
17713        if (canGcNowLocked()) {
17714            performAppGcsLocked();
17715            return;
17716        }
17717        // Still not idle, wait some more.
17718        scheduleAppGcsLocked();
17719    }
17720
17721    /**
17722     * Schedule the execution of all pending app GCs.
17723     */
17724    final void scheduleAppGcsLocked() {
17725        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17726
17727        if (mProcessesToGc.size() > 0) {
17728            // Schedule a GC for the time to the next process.
17729            ProcessRecord proc = mProcessesToGc.get(0);
17730            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17731
17732            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17733            long now = SystemClock.uptimeMillis();
17734            if (when < (now+GC_TIMEOUT)) {
17735                when = now + GC_TIMEOUT;
17736            }
17737            mHandler.sendMessageAtTime(msg, when);
17738        }
17739    }
17740
17741    /**
17742     * Add a process to the array of processes waiting to be GCed.  Keeps the
17743     * list in sorted order by the last GC time.  The process can't already be
17744     * on the list.
17745     */
17746    final void addProcessToGcListLocked(ProcessRecord proc) {
17747        boolean added = false;
17748        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17749            if (mProcessesToGc.get(i).lastRequestedGc <
17750                    proc.lastRequestedGc) {
17751                added = true;
17752                mProcessesToGc.add(i+1, proc);
17753                break;
17754            }
17755        }
17756        if (!added) {
17757            mProcessesToGc.add(0, proc);
17758        }
17759    }
17760
17761    /**
17762     * Set up to ask a process to GC itself.  This will either do it
17763     * immediately, or put it on the list of processes to gc the next
17764     * time things are idle.
17765     */
17766    final void scheduleAppGcLocked(ProcessRecord app) {
17767        long now = SystemClock.uptimeMillis();
17768        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17769            return;
17770        }
17771        if (!mProcessesToGc.contains(app)) {
17772            addProcessToGcListLocked(app);
17773            scheduleAppGcsLocked();
17774        }
17775    }
17776
17777    final void checkExcessivePowerUsageLocked(boolean doKills) {
17778        updateCpuStatsNow();
17779
17780        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17781        boolean doWakeKills = doKills;
17782        boolean doCpuKills = doKills;
17783        if (mLastPowerCheckRealtime == 0) {
17784            doWakeKills = false;
17785        }
17786        if (mLastPowerCheckUptime == 0) {
17787            doCpuKills = false;
17788        }
17789        if (stats.isScreenOn()) {
17790            doWakeKills = false;
17791        }
17792        final long curRealtime = SystemClock.elapsedRealtime();
17793        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17794        final long curUptime = SystemClock.uptimeMillis();
17795        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17796        mLastPowerCheckRealtime = curRealtime;
17797        mLastPowerCheckUptime = curUptime;
17798        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17799            doWakeKills = false;
17800        }
17801        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17802            doCpuKills = false;
17803        }
17804        int i = mLruProcesses.size();
17805        while (i > 0) {
17806            i--;
17807            ProcessRecord app = mLruProcesses.get(i);
17808            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17809                long wtime;
17810                synchronized (stats) {
17811                    wtime = stats.getProcessWakeTime(app.info.uid,
17812                            app.pid, curRealtime);
17813                }
17814                long wtimeUsed = wtime - app.lastWakeTime;
17815                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17816                if (DEBUG_POWER) {
17817                    StringBuilder sb = new StringBuilder(128);
17818                    sb.append("Wake for ");
17819                    app.toShortString(sb);
17820                    sb.append(": over ");
17821                    TimeUtils.formatDuration(realtimeSince, sb);
17822                    sb.append(" used ");
17823                    TimeUtils.formatDuration(wtimeUsed, sb);
17824                    sb.append(" (");
17825                    sb.append((wtimeUsed*100)/realtimeSince);
17826                    sb.append("%)");
17827                    Slog.i(TAG, sb.toString());
17828                    sb.setLength(0);
17829                    sb.append("CPU for ");
17830                    app.toShortString(sb);
17831                    sb.append(": over ");
17832                    TimeUtils.formatDuration(uptimeSince, sb);
17833                    sb.append(" used ");
17834                    TimeUtils.formatDuration(cputimeUsed, sb);
17835                    sb.append(" (");
17836                    sb.append((cputimeUsed*100)/uptimeSince);
17837                    sb.append("%)");
17838                    Slog.i(TAG, sb.toString());
17839                }
17840                // If a process has held a wake lock for more
17841                // than 50% of the time during this period,
17842                // that sounds bad.  Kill!
17843                if (doWakeKills && realtimeSince > 0
17844                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17845                    synchronized (stats) {
17846                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17847                                realtimeSince, wtimeUsed);
17848                    }
17849                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17850                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17851                } else if (doCpuKills && uptimeSince > 0
17852                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17853                    synchronized (stats) {
17854                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17855                                uptimeSince, cputimeUsed);
17856                    }
17857                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17858                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17859                } else {
17860                    app.lastWakeTime = wtime;
17861                    app.lastCpuTime = app.curCpuTime;
17862                }
17863            }
17864        }
17865    }
17866
17867    private final boolean applyOomAdjLocked(ProcessRecord app,
17868            ProcessRecord TOP_APP, boolean doingAll, long now) {
17869        boolean success = true;
17870
17871        if (app.curRawAdj != app.setRawAdj) {
17872            app.setRawAdj = app.curRawAdj;
17873        }
17874
17875        int changes = 0;
17876
17877        if (app.curAdj != app.setAdj) {
17878            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17879            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17880                TAG, "Set " + app.pid + " " + app.processName +
17881                " adj " + app.curAdj + ": " + app.adjType);
17882            app.setAdj = app.curAdj;
17883        }
17884
17885        if (app.setSchedGroup != app.curSchedGroup) {
17886            app.setSchedGroup = app.curSchedGroup;
17887            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17888                    "Setting process group of " + app.processName
17889                    + " to " + app.curSchedGroup);
17890            if (app.waitingToKill != null &&
17891                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17892                app.kill(app.waitingToKill, true);
17893                success = false;
17894            } else {
17895                if (true) {
17896                    long oldId = Binder.clearCallingIdentity();
17897                    try {
17898                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17899                    } catch (Exception e) {
17900                        Slog.w(TAG, "Failed setting process group of " + app.pid
17901                                + " to " + app.curSchedGroup);
17902                        e.printStackTrace();
17903                    } finally {
17904                        Binder.restoreCallingIdentity(oldId);
17905                    }
17906                } else {
17907                    if (app.thread != null) {
17908                        try {
17909                            app.thread.setSchedulingGroup(app.curSchedGroup);
17910                        } catch (RemoteException e) {
17911                        }
17912                    }
17913                }
17914                Process.setSwappiness(app.pid,
17915                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17916            }
17917        }
17918        if (app.repForegroundActivities != app.foregroundActivities) {
17919            app.repForegroundActivities = app.foregroundActivities;
17920            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17921        }
17922        if (app.repProcState != app.curProcState) {
17923            app.repProcState = app.curProcState;
17924            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17925            if (app.thread != null) {
17926                try {
17927                    if (false) {
17928                        //RuntimeException h = new RuntimeException("here");
17929                        Slog.i(TAG, "Sending new process state " + app.repProcState
17930                                + " to " + app /*, h*/);
17931                    }
17932                    app.thread.setProcessState(app.repProcState);
17933                } catch (RemoteException e) {
17934                }
17935            }
17936        }
17937        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17938                app.setProcState)) {
17939            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17940                // Experimental code to more aggressively collect pss while
17941                // running test...  the problem is that this tends to collect
17942                // the data right when a process is transitioning between process
17943                // states, which well tend to give noisy data.
17944                long start = SystemClock.uptimeMillis();
17945                long pss = Debug.getPss(app.pid, mTmpLong, null);
17946                recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
17947                mPendingPssProcesses.remove(app);
17948                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17949                        + " to " + app.curProcState + ": "
17950                        + (SystemClock.uptimeMillis()-start) + "ms");
17951            }
17952            app.lastStateTime = now;
17953            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17954                    mTestPssMode, isSleeping(), now);
17955            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17956                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17957                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17958                    + (app.nextPssTime-now) + ": " + app);
17959        } else {
17960            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17961                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
17962                    mTestPssMode)))) {
17963                requestPssLocked(app, app.setProcState);
17964                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17965                        mTestPssMode, isSleeping(), now);
17966            } else if (false && DEBUG_PSS) {
17967                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17968            }
17969        }
17970        if (app.setProcState != app.curProcState) {
17971            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17972                    "Proc state change of " + app.processName
17973                    + " to " + app.curProcState);
17974            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17975            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17976            if (setImportant && !curImportant) {
17977                // This app is no longer something we consider important enough to allow to
17978                // use arbitrary amounts of battery power.  Note
17979                // its current wake lock time to later know to kill it if
17980                // it is not behaving well.
17981                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17982                synchronized (stats) {
17983                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17984                            app.pid, SystemClock.elapsedRealtime());
17985                }
17986                app.lastCpuTime = app.curCpuTime;
17987
17988            }
17989            app.setProcState = app.curProcState;
17990            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17991                app.notCachedSinceIdle = false;
17992            }
17993            if (!doingAll) {
17994                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17995            } else {
17996                app.procStateChanged = true;
17997            }
17998        }
17999
18000        if (changes != 0) {
18001            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
18002            int i = mPendingProcessChanges.size()-1;
18003            ProcessChangeItem item = null;
18004            while (i >= 0) {
18005                item = mPendingProcessChanges.get(i);
18006                if (item.pid == app.pid) {
18007                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
18008                    break;
18009                }
18010                i--;
18011            }
18012            if (i < 0) {
18013                // No existing item in pending changes; need a new one.
18014                final int NA = mAvailProcessChanges.size();
18015                if (NA > 0) {
18016                    item = mAvailProcessChanges.remove(NA-1);
18017                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
18018                } else {
18019                    item = new ProcessChangeItem();
18020                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
18021                }
18022                item.changes = 0;
18023                item.pid = app.pid;
18024                item.uid = app.info.uid;
18025                if (mPendingProcessChanges.size() == 0) {
18026                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
18027                            "*** Enqueueing dispatch processes changed!");
18028                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18029                }
18030                mPendingProcessChanges.add(item);
18031            }
18032            item.changes |= changes;
18033            item.processState = app.repProcState;
18034            item.foregroundActivities = app.repForegroundActivities;
18035            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
18036                    + Integer.toHexString(System.identityHashCode(item))
18037                    + " " + app.toShortString() + ": changes=" + item.changes
18038                    + " procState=" + item.processState
18039                    + " foreground=" + item.foregroundActivities
18040                    + " type=" + app.adjType + " source=" + app.adjSource
18041                    + " target=" + app.adjTarget);
18042        }
18043
18044        return success;
18045    }
18046
18047    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18048        if (proc.thread != null) {
18049            if (proc.baseProcessTracker != null) {
18050                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18051            }
18052            if (proc.repProcState >= 0) {
18053                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18054                        proc.repProcState);
18055            }
18056        }
18057    }
18058
18059    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18060            ProcessRecord TOP_APP, boolean doingAll, long now) {
18061        if (app.thread == null) {
18062            return false;
18063        }
18064
18065        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18066
18067        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
18068    }
18069
18070    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18071            boolean oomAdj) {
18072        if (isForeground != proc.foregroundServices) {
18073            proc.foregroundServices = isForeground;
18074            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18075                    proc.info.uid);
18076            if (isForeground) {
18077                if (curProcs == null) {
18078                    curProcs = new ArrayList<ProcessRecord>();
18079                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18080                }
18081                if (!curProcs.contains(proc)) {
18082                    curProcs.add(proc);
18083                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18084                            proc.info.packageName, proc.info.uid);
18085                }
18086            } else {
18087                if (curProcs != null) {
18088                    if (curProcs.remove(proc)) {
18089                        mBatteryStatsService.noteEvent(
18090                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18091                                proc.info.packageName, proc.info.uid);
18092                        if (curProcs.size() <= 0) {
18093                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18094                        }
18095                    }
18096                }
18097            }
18098            if (oomAdj) {
18099                updateOomAdjLocked();
18100            }
18101        }
18102    }
18103
18104    private final ActivityRecord resumedAppLocked() {
18105        ActivityRecord act = mStackSupervisor.resumedAppLocked();
18106        String pkg;
18107        int uid;
18108        if (act != null) {
18109            pkg = act.packageName;
18110            uid = act.info.applicationInfo.uid;
18111        } else {
18112            pkg = null;
18113            uid = -1;
18114        }
18115        // Has the UID or resumed package name changed?
18116        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18117                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18118            if (mCurResumedPackage != null) {
18119                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18120                        mCurResumedPackage, mCurResumedUid);
18121            }
18122            mCurResumedPackage = pkg;
18123            mCurResumedUid = uid;
18124            if (mCurResumedPackage != null) {
18125                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18126                        mCurResumedPackage, mCurResumedUid);
18127            }
18128        }
18129        return act;
18130    }
18131
18132    final boolean updateOomAdjLocked(ProcessRecord app) {
18133        final ActivityRecord TOP_ACT = resumedAppLocked();
18134        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18135        final boolean wasCached = app.cached;
18136
18137        mAdjSeq++;
18138
18139        // This is the desired cached adjusment we want to tell it to use.
18140        // If our app is currently cached, we know it, and that is it.  Otherwise,
18141        // we don't know it yet, and it needs to now be cached we will then
18142        // need to do a complete oom adj.
18143        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18144                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18145        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18146                SystemClock.uptimeMillis());
18147        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18148            // Changed to/from cached state, so apps after it in the LRU
18149            // list may also be changed.
18150            updateOomAdjLocked();
18151        }
18152        return success;
18153    }
18154
18155    final void updateOomAdjLocked() {
18156        final ActivityRecord TOP_ACT = resumedAppLocked();
18157        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18158        final long now = SystemClock.uptimeMillis();
18159        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18160        final int N = mLruProcesses.size();
18161
18162        if (false) {
18163            RuntimeException e = new RuntimeException();
18164            e.fillInStackTrace();
18165            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18166        }
18167
18168        mAdjSeq++;
18169        mNewNumServiceProcs = 0;
18170        mNewNumAServiceProcs = 0;
18171
18172        final int emptyProcessLimit;
18173        final int cachedProcessLimit;
18174        if (mProcessLimit <= 0) {
18175            emptyProcessLimit = cachedProcessLimit = 0;
18176        } else if (mProcessLimit == 1) {
18177            emptyProcessLimit = 1;
18178            cachedProcessLimit = 0;
18179        } else {
18180            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18181            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18182        }
18183
18184        // Let's determine how many processes we have running vs.
18185        // how many slots we have for background processes; we may want
18186        // to put multiple processes in a slot of there are enough of
18187        // them.
18188        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18189                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18190        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18191        if (numEmptyProcs > cachedProcessLimit) {
18192            // If there are more empty processes than our limit on cached
18193            // processes, then use the cached process limit for the factor.
18194            // This ensures that the really old empty processes get pushed
18195            // down to the bottom, so if we are running low on memory we will
18196            // have a better chance at keeping around more cached processes
18197            // instead of a gazillion empty processes.
18198            numEmptyProcs = cachedProcessLimit;
18199        }
18200        int emptyFactor = numEmptyProcs/numSlots;
18201        if (emptyFactor < 1) emptyFactor = 1;
18202        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18203        if (cachedFactor < 1) cachedFactor = 1;
18204        int stepCached = 0;
18205        int stepEmpty = 0;
18206        int numCached = 0;
18207        int numEmpty = 0;
18208        int numTrimming = 0;
18209
18210        mNumNonCachedProcs = 0;
18211        mNumCachedHiddenProcs = 0;
18212
18213        // First update the OOM adjustment for each of the
18214        // application processes based on their current state.
18215        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18216        int nextCachedAdj = curCachedAdj+1;
18217        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18218        int nextEmptyAdj = curEmptyAdj+2;
18219        for (int i=N-1; i>=0; i--) {
18220            ProcessRecord app = mLruProcesses.get(i);
18221            if (!app.killedByAm && app.thread != null) {
18222                app.procStateChanged = false;
18223                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18224
18225                // If we haven't yet assigned the final cached adj
18226                // to the process, do that now.
18227                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18228                    switch (app.curProcState) {
18229                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18230                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18231                            // This process is a cached process holding activities...
18232                            // assign it the next cached value for that type, and then
18233                            // step that cached level.
18234                            app.curRawAdj = curCachedAdj;
18235                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18236                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18237                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18238                                    + ")");
18239                            if (curCachedAdj != nextCachedAdj) {
18240                                stepCached++;
18241                                if (stepCached >= cachedFactor) {
18242                                    stepCached = 0;
18243                                    curCachedAdj = nextCachedAdj;
18244                                    nextCachedAdj += 2;
18245                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18246                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18247                                    }
18248                                }
18249                            }
18250                            break;
18251                        default:
18252                            // For everything else, assign next empty cached process
18253                            // level and bump that up.  Note that this means that
18254                            // long-running services that have dropped down to the
18255                            // cached level will be treated as empty (since their process
18256                            // state is still as a service), which is what we want.
18257                            app.curRawAdj = curEmptyAdj;
18258                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18259                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18260                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18261                                    + ")");
18262                            if (curEmptyAdj != nextEmptyAdj) {
18263                                stepEmpty++;
18264                                if (stepEmpty >= emptyFactor) {
18265                                    stepEmpty = 0;
18266                                    curEmptyAdj = nextEmptyAdj;
18267                                    nextEmptyAdj += 2;
18268                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18269                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18270                                    }
18271                                }
18272                            }
18273                            break;
18274                    }
18275                }
18276
18277                applyOomAdjLocked(app, TOP_APP, true, now);
18278
18279                // Count the number of process types.
18280                switch (app.curProcState) {
18281                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18282                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18283                        mNumCachedHiddenProcs++;
18284                        numCached++;
18285                        if (numCached > cachedProcessLimit) {
18286                            app.kill("cached #" + numCached, true);
18287                        }
18288                        break;
18289                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18290                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18291                                && app.lastActivityTime < oldTime) {
18292                            app.kill("empty for "
18293                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18294                                    / 1000) + "s", true);
18295                        } else {
18296                            numEmpty++;
18297                            if (numEmpty > emptyProcessLimit) {
18298                                app.kill("empty #" + numEmpty, true);
18299                            }
18300                        }
18301                        break;
18302                    default:
18303                        mNumNonCachedProcs++;
18304                        break;
18305                }
18306
18307                if (app.isolated && app.services.size() <= 0) {
18308                    // If this is an isolated process, and there are no
18309                    // services running in it, then the process is no longer
18310                    // needed.  We agressively kill these because we can by
18311                    // definition not re-use the same process again, and it is
18312                    // good to avoid having whatever code was running in them
18313                    // left sitting around after no longer needed.
18314                    app.kill("isolated not needed", true);
18315                }
18316
18317                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18318                        && !app.killedByAm) {
18319                    numTrimming++;
18320                }
18321            }
18322        }
18323
18324        mNumServiceProcs = mNewNumServiceProcs;
18325
18326        // Now determine the memory trimming level of background processes.
18327        // Unfortunately we need to start at the back of the list to do this
18328        // properly.  We only do this if the number of background apps we
18329        // are managing to keep around is less than half the maximum we desire;
18330        // if we are keeping a good number around, we'll let them use whatever
18331        // memory they want.
18332        final int numCachedAndEmpty = numCached + numEmpty;
18333        int memFactor;
18334        if (numCached <= ProcessList.TRIM_CACHED_APPS
18335                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18336            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18337                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18338            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18339                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18340            } else {
18341                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18342            }
18343        } else {
18344            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18345        }
18346        // We always allow the memory level to go up (better).  We only allow it to go
18347        // down if we are in a state where that is allowed, *and* the total number of processes
18348        // has gone down since last time.
18349        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18350                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18351                + " last=" + mLastNumProcesses);
18352        if (memFactor > mLastMemoryLevel) {
18353            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18354                memFactor = mLastMemoryLevel;
18355                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18356            }
18357        }
18358        mLastMemoryLevel = memFactor;
18359        mLastNumProcesses = mLruProcesses.size();
18360        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18361        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18362        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18363            if (mLowRamStartTime == 0) {
18364                mLowRamStartTime = now;
18365            }
18366            int step = 0;
18367            int fgTrimLevel;
18368            switch (memFactor) {
18369                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18370                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18371                    break;
18372                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18373                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18374                    break;
18375                default:
18376                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18377                    break;
18378            }
18379            int factor = numTrimming/3;
18380            int minFactor = 2;
18381            if (mHomeProcess != null) minFactor++;
18382            if (mPreviousProcess != null) minFactor++;
18383            if (factor < minFactor) factor = minFactor;
18384            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18385            for (int i=N-1; i>=0; i--) {
18386                ProcessRecord app = mLruProcesses.get(i);
18387                if (allChanged || app.procStateChanged) {
18388                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18389                    app.procStateChanged = false;
18390                }
18391                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18392                        && !app.killedByAm) {
18393                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18394                        try {
18395                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18396                                    "Trimming memory of " + app.processName
18397                                    + " to " + curLevel);
18398                            app.thread.scheduleTrimMemory(curLevel);
18399                        } catch (RemoteException e) {
18400                        }
18401                        if (false) {
18402                            // For now we won't do this; our memory trimming seems
18403                            // to be good enough at this point that destroying
18404                            // activities causes more harm than good.
18405                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18406                                    && app != mHomeProcess && app != mPreviousProcess) {
18407                                // Need to do this on its own message because the stack may not
18408                                // be in a consistent state at this point.
18409                                // For these apps we will also finish their activities
18410                                // to help them free memory.
18411                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18412                            }
18413                        }
18414                    }
18415                    app.trimMemoryLevel = curLevel;
18416                    step++;
18417                    if (step >= factor) {
18418                        step = 0;
18419                        switch (curLevel) {
18420                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18421                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18422                                break;
18423                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18424                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18425                                break;
18426                        }
18427                    }
18428                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18429                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18430                            && app.thread != null) {
18431                        try {
18432                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18433                                    "Trimming memory of heavy-weight " + app.processName
18434                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18435                            app.thread.scheduleTrimMemory(
18436                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18437                        } catch (RemoteException e) {
18438                        }
18439                    }
18440                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18441                } else {
18442                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18443                            || app.systemNoUi) && app.pendingUiClean) {
18444                        // If this application is now in the background and it
18445                        // had done UI, then give it the special trim level to
18446                        // have it free UI resources.
18447                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18448                        if (app.trimMemoryLevel < level && app.thread != null) {
18449                            try {
18450                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18451                                        "Trimming memory of bg-ui " + app.processName
18452                                        + " to " + level);
18453                                app.thread.scheduleTrimMemory(level);
18454                            } catch (RemoteException e) {
18455                            }
18456                        }
18457                        app.pendingUiClean = false;
18458                    }
18459                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18460                        try {
18461                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18462                                    "Trimming memory of fg " + app.processName
18463                                    + " to " + fgTrimLevel);
18464                            app.thread.scheduleTrimMemory(fgTrimLevel);
18465                        } catch (RemoteException e) {
18466                        }
18467                    }
18468                    app.trimMemoryLevel = fgTrimLevel;
18469                }
18470            }
18471        } else {
18472            if (mLowRamStartTime != 0) {
18473                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18474                mLowRamStartTime = 0;
18475            }
18476            for (int i=N-1; i>=0; i--) {
18477                ProcessRecord app = mLruProcesses.get(i);
18478                if (allChanged || app.procStateChanged) {
18479                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18480                    app.procStateChanged = false;
18481                }
18482                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18483                        || app.systemNoUi) && app.pendingUiClean) {
18484                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18485                            && app.thread != null) {
18486                        try {
18487                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18488                                    "Trimming memory of ui hidden " + app.processName
18489                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18490                            app.thread.scheduleTrimMemory(
18491                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18492                        } catch (RemoteException e) {
18493                        }
18494                    }
18495                    app.pendingUiClean = false;
18496                }
18497                app.trimMemoryLevel = 0;
18498            }
18499        }
18500
18501        if (mAlwaysFinishActivities) {
18502            // Need to do this on its own message because the stack may not
18503            // be in a consistent state at this point.
18504            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18505        }
18506
18507        if (allChanged) {
18508            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18509        }
18510
18511        if (mProcessStats.shouldWriteNowLocked(now)) {
18512            mHandler.post(new Runnable() {
18513                @Override public void run() {
18514                    synchronized (ActivityManagerService.this) {
18515                        mProcessStats.writeStateAsyncLocked();
18516                    }
18517                }
18518            });
18519        }
18520
18521        if (DEBUG_OOM_ADJ) {
18522            if (false) {
18523                RuntimeException here = new RuntimeException("here");
18524                here.fillInStackTrace();
18525                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18526            } else {
18527                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18528            }
18529        }
18530    }
18531
18532    final void trimApplications() {
18533        synchronized (this) {
18534            int i;
18535
18536            // First remove any unused application processes whose package
18537            // has been removed.
18538            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18539                final ProcessRecord app = mRemovedProcesses.get(i);
18540                if (app.activities.size() == 0
18541                        && app.curReceiver == null && app.services.size() == 0) {
18542                    Slog.i(
18543                        TAG, "Exiting empty application process "
18544                        + app.processName + " ("
18545                        + (app.thread != null ? app.thread.asBinder() : null)
18546                        + ")\n");
18547                    if (app.pid > 0 && app.pid != MY_PID) {
18548                        app.kill("empty", false);
18549                    } else {
18550                        try {
18551                            app.thread.scheduleExit();
18552                        } catch (Exception e) {
18553                            // Ignore exceptions.
18554                        }
18555                    }
18556                    cleanUpApplicationRecordLocked(app, false, true, -1);
18557                    mRemovedProcesses.remove(i);
18558
18559                    if (app.persistent) {
18560                        addAppLocked(app.info, false, null /* ABI override */);
18561                    }
18562                }
18563            }
18564
18565            // Now update the oom adj for all processes.
18566            updateOomAdjLocked();
18567        }
18568    }
18569
18570    /** This method sends the specified signal to each of the persistent apps */
18571    public void signalPersistentProcesses(int sig) throws RemoteException {
18572        if (sig != Process.SIGNAL_USR1) {
18573            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18574        }
18575
18576        synchronized (this) {
18577            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18578                    != PackageManager.PERMISSION_GRANTED) {
18579                throw new SecurityException("Requires permission "
18580                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18581            }
18582
18583            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18584                ProcessRecord r = mLruProcesses.get(i);
18585                if (r.thread != null && r.persistent) {
18586                    Process.sendSignal(r.pid, sig);
18587                }
18588            }
18589        }
18590    }
18591
18592    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18593        if (proc == null || proc == mProfileProc) {
18594            proc = mProfileProc;
18595            profileType = mProfileType;
18596            clearProfilerLocked();
18597        }
18598        if (proc == null) {
18599            return;
18600        }
18601        try {
18602            proc.thread.profilerControl(false, null, profileType);
18603        } catch (RemoteException e) {
18604            throw new IllegalStateException("Process disappeared");
18605        }
18606    }
18607
18608    private void clearProfilerLocked() {
18609        if (mProfileFd != null) {
18610            try {
18611                mProfileFd.close();
18612            } catch (IOException e) {
18613            }
18614        }
18615        mProfileApp = null;
18616        mProfileProc = null;
18617        mProfileFile = null;
18618        mProfileType = 0;
18619        mAutoStopProfiler = false;
18620        mSamplingInterval = 0;
18621    }
18622
18623    public boolean profileControl(String process, int userId, boolean start,
18624            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18625
18626        try {
18627            synchronized (this) {
18628                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18629                // its own permission.
18630                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18631                        != PackageManager.PERMISSION_GRANTED) {
18632                    throw new SecurityException("Requires permission "
18633                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18634                }
18635
18636                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18637                    throw new IllegalArgumentException("null profile info or fd");
18638                }
18639
18640                ProcessRecord proc = null;
18641                if (process != null) {
18642                    proc = findProcessLocked(process, userId, "profileControl");
18643                }
18644
18645                if (start && (proc == null || proc.thread == null)) {
18646                    throw new IllegalArgumentException("Unknown process: " + process);
18647                }
18648
18649                if (start) {
18650                    stopProfilerLocked(null, 0);
18651                    setProfileApp(proc.info, proc.processName, profilerInfo);
18652                    mProfileProc = proc;
18653                    mProfileType = profileType;
18654                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18655                    try {
18656                        fd = fd.dup();
18657                    } catch (IOException e) {
18658                        fd = null;
18659                    }
18660                    profilerInfo.profileFd = fd;
18661                    proc.thread.profilerControl(start, profilerInfo, profileType);
18662                    fd = null;
18663                    mProfileFd = null;
18664                } else {
18665                    stopProfilerLocked(proc, profileType);
18666                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18667                        try {
18668                            profilerInfo.profileFd.close();
18669                        } catch (IOException e) {
18670                        }
18671                    }
18672                }
18673
18674                return true;
18675            }
18676        } catch (RemoteException e) {
18677            throw new IllegalStateException("Process disappeared");
18678        } finally {
18679            if (profilerInfo != null && profilerInfo.profileFd != null) {
18680                try {
18681                    profilerInfo.profileFd.close();
18682                } catch (IOException e) {
18683                }
18684            }
18685        }
18686    }
18687
18688    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18689        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18690                userId, true, ALLOW_FULL_ONLY, callName, null);
18691        ProcessRecord proc = null;
18692        try {
18693            int pid = Integer.parseInt(process);
18694            synchronized (mPidsSelfLocked) {
18695                proc = mPidsSelfLocked.get(pid);
18696            }
18697        } catch (NumberFormatException e) {
18698        }
18699
18700        if (proc == null) {
18701            ArrayMap<String, SparseArray<ProcessRecord>> all
18702                    = mProcessNames.getMap();
18703            SparseArray<ProcessRecord> procs = all.get(process);
18704            if (procs != null && procs.size() > 0) {
18705                proc = procs.valueAt(0);
18706                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18707                    for (int i=1; i<procs.size(); i++) {
18708                        ProcessRecord thisProc = procs.valueAt(i);
18709                        if (thisProc.userId == userId) {
18710                            proc = thisProc;
18711                            break;
18712                        }
18713                    }
18714                }
18715            }
18716        }
18717
18718        return proc;
18719    }
18720
18721    public boolean dumpHeap(String process, int userId, boolean managed,
18722            String path, ParcelFileDescriptor fd) throws RemoteException {
18723
18724        try {
18725            synchronized (this) {
18726                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18727                // its own permission (same as profileControl).
18728                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18729                        != PackageManager.PERMISSION_GRANTED) {
18730                    throw new SecurityException("Requires permission "
18731                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18732                }
18733
18734                if (fd == null) {
18735                    throw new IllegalArgumentException("null fd");
18736                }
18737
18738                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18739                if (proc == null || proc.thread == null) {
18740                    throw new IllegalArgumentException("Unknown process: " + process);
18741                }
18742
18743                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18744                if (!isDebuggable) {
18745                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18746                        throw new SecurityException("Process not debuggable: " + proc);
18747                    }
18748                }
18749
18750                proc.thread.dumpHeap(managed, path, fd);
18751                fd = null;
18752                return true;
18753            }
18754        } catch (RemoteException e) {
18755            throw new IllegalStateException("Process disappeared");
18756        } finally {
18757            if (fd != null) {
18758                try {
18759                    fd.close();
18760                } catch (IOException e) {
18761                }
18762            }
18763        }
18764    }
18765
18766    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18767    public void monitor() {
18768        synchronized (this) { }
18769    }
18770
18771    void onCoreSettingsChange(Bundle settings) {
18772        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18773            ProcessRecord processRecord = mLruProcesses.get(i);
18774            try {
18775                if (processRecord.thread != null) {
18776                    processRecord.thread.setCoreSettings(settings);
18777                }
18778            } catch (RemoteException re) {
18779                /* ignore */
18780            }
18781        }
18782    }
18783
18784    // Multi-user methods
18785
18786    /**
18787     * Start user, if its not already running, but don't bring it to foreground.
18788     */
18789    @Override
18790    public boolean startUserInBackground(final int userId) {
18791        return startUser(userId, /* foreground */ false);
18792    }
18793
18794    /**
18795     * Start user, if its not already running, and bring it to foreground.
18796     */
18797    boolean startUserInForeground(final int userId, Dialog dlg) {
18798        boolean result = startUser(userId, /* foreground */ true);
18799        dlg.dismiss();
18800        return result;
18801    }
18802
18803    /**
18804     * Refreshes the list of users related to the current user when either a
18805     * user switch happens or when a new related user is started in the
18806     * background.
18807     */
18808    private void updateCurrentProfileIdsLocked() {
18809        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18810                mCurrentUserId, false /* enabledOnly */);
18811        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18812        for (int i = 0; i < currentProfileIds.length; i++) {
18813            currentProfileIds[i] = profiles.get(i).id;
18814        }
18815        mCurrentProfileIds = currentProfileIds;
18816
18817        synchronized (mUserProfileGroupIdsSelfLocked) {
18818            mUserProfileGroupIdsSelfLocked.clear();
18819            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18820            for (int i = 0; i < users.size(); i++) {
18821                UserInfo user = users.get(i);
18822                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18823                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18824                }
18825            }
18826        }
18827    }
18828
18829    private Set getProfileIdsLocked(int userId) {
18830        Set userIds = new HashSet<Integer>();
18831        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18832                userId, false /* enabledOnly */);
18833        for (UserInfo user : profiles) {
18834            userIds.add(Integer.valueOf(user.id));
18835        }
18836        return userIds;
18837    }
18838
18839    @Override
18840    public boolean switchUser(final int userId) {
18841        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18842        String userName;
18843        synchronized (this) {
18844            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18845            if (userInfo == null) {
18846                Slog.w(TAG, "No user info for user #" + userId);
18847                return false;
18848            }
18849            if (userInfo.isManagedProfile()) {
18850                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18851                return false;
18852            }
18853            userName = userInfo.name;
18854            mTargetUserId = userId;
18855        }
18856        mHandler.removeMessages(START_USER_SWITCH_MSG);
18857        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18858        return true;
18859    }
18860
18861    private void showUserSwitchDialog(int userId, String userName) {
18862        // The dialog will show and then initiate the user switch by calling startUserInForeground
18863        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18864                true /* above system */);
18865        d.show();
18866    }
18867
18868    private boolean startUser(final int userId, final boolean foreground) {
18869        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18870                != PackageManager.PERMISSION_GRANTED) {
18871            String msg = "Permission Denial: switchUser() from pid="
18872                    + Binder.getCallingPid()
18873                    + ", uid=" + Binder.getCallingUid()
18874                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18875            Slog.w(TAG, msg);
18876            throw new SecurityException(msg);
18877        }
18878
18879        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18880
18881        final long ident = Binder.clearCallingIdentity();
18882        try {
18883            synchronized (this) {
18884                final int oldUserId = mCurrentUserId;
18885                if (oldUserId == userId) {
18886                    return true;
18887                }
18888
18889                mStackSupervisor.setLockTaskModeLocked(null, false, "startUser");
18890
18891                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18892                if (userInfo == null) {
18893                    Slog.w(TAG, "No user info for user #" + userId);
18894                    return false;
18895                }
18896                if (foreground && userInfo.isManagedProfile()) {
18897                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18898                    return false;
18899                }
18900
18901                if (foreground) {
18902                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18903                            R.anim.screen_user_enter);
18904                }
18905
18906                boolean needStart = false;
18907
18908                // If the user we are switching to is not currently started, then
18909                // we need to start it now.
18910                if (mStartedUsers.get(userId) == null) {
18911                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18912                    updateStartedUserArrayLocked();
18913                    needStart = true;
18914                }
18915
18916                final Integer userIdInt = Integer.valueOf(userId);
18917                mUserLru.remove(userIdInt);
18918                mUserLru.add(userIdInt);
18919
18920                if (foreground) {
18921                    mCurrentUserId = userId;
18922                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18923                    updateCurrentProfileIdsLocked();
18924                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18925                    // Once the internal notion of the active user has switched, we lock the device
18926                    // with the option to show the user switcher on the keyguard.
18927                    mWindowManager.lockNow(null);
18928                } else {
18929                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18930                    updateCurrentProfileIdsLocked();
18931                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18932                    mUserLru.remove(currentUserIdInt);
18933                    mUserLru.add(currentUserIdInt);
18934                }
18935
18936                final UserStartedState uss = mStartedUsers.get(userId);
18937
18938                // Make sure user is in the started state.  If it is currently
18939                // stopping, we need to knock that off.
18940                if (uss.mState == UserStartedState.STATE_STOPPING) {
18941                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18942                    // so we can just fairly silently bring the user back from
18943                    // the almost-dead.
18944                    uss.mState = UserStartedState.STATE_RUNNING;
18945                    updateStartedUserArrayLocked();
18946                    needStart = true;
18947                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18948                    // This means ACTION_SHUTDOWN has been sent, so we will
18949                    // need to treat this as a new boot of the user.
18950                    uss.mState = UserStartedState.STATE_BOOTING;
18951                    updateStartedUserArrayLocked();
18952                    needStart = true;
18953                }
18954
18955                if (uss.mState == UserStartedState.STATE_BOOTING) {
18956                    // Booting up a new user, need to tell system services about it.
18957                    // Note that this is on the same handler as scheduling of broadcasts,
18958                    // which is important because it needs to go first.
18959                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18960                }
18961
18962                if (foreground) {
18963                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18964                            oldUserId));
18965                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18966                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18967                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18968                            oldUserId, userId, uss));
18969                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18970                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18971                }
18972
18973                if (needStart) {
18974                    // Send USER_STARTED broadcast
18975                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18976                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18977                            | Intent.FLAG_RECEIVER_FOREGROUND);
18978                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18979                    broadcastIntentLocked(null, null, intent,
18980                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18981                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18982                }
18983
18984                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18985                    if (userId != UserHandle.USER_OWNER) {
18986                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18987                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18988                        broadcastIntentLocked(null, null, intent, null,
18989                                new IIntentReceiver.Stub() {
18990                                    public void performReceive(Intent intent, int resultCode,
18991                                            String data, Bundle extras, boolean ordered,
18992                                            boolean sticky, int sendingUser) {
18993                                        onUserInitialized(uss, foreground, oldUserId, userId);
18994                                    }
18995                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18996                                true, false, MY_PID, Process.SYSTEM_UID,
18997                                userId);
18998                        uss.initializing = true;
18999                    } else {
19000                        getUserManagerLocked().makeInitialized(userInfo.id);
19001                    }
19002                }
19003
19004                if (foreground) {
19005                    if (!uss.initializing) {
19006                        moveUserToForeground(uss, oldUserId, userId);
19007                    }
19008                } else {
19009                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
19010                }
19011
19012                if (needStart) {
19013                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19014                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19015                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19016                    broadcastIntentLocked(null, null, intent,
19017                            null, new IIntentReceiver.Stub() {
19018                                @Override
19019                                public void performReceive(Intent intent, int resultCode, String data,
19020                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
19021                                        throws RemoteException {
19022                                }
19023                            }, 0, null, null,
19024                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19025                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19026                }
19027            }
19028        } finally {
19029            Binder.restoreCallingIdentity(ident);
19030        }
19031
19032        return true;
19033    }
19034
19035    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19036        long ident = Binder.clearCallingIdentity();
19037        try {
19038            Intent intent;
19039            if (oldUserId >= 0) {
19040                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19041                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19042                int count = profiles.size();
19043                for (int i = 0; i < count; i++) {
19044                    int profileUserId = profiles.get(i).id;
19045                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19046                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19047                            | Intent.FLAG_RECEIVER_FOREGROUND);
19048                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19049                    broadcastIntentLocked(null, null, intent,
19050                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19051                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19052                }
19053            }
19054            if (newUserId >= 0) {
19055                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19056                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19057                int count = profiles.size();
19058                for (int i = 0; i < count; i++) {
19059                    int profileUserId = profiles.get(i).id;
19060                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19061                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19062                            | Intent.FLAG_RECEIVER_FOREGROUND);
19063                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19064                    broadcastIntentLocked(null, null, intent,
19065                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19066                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19067                }
19068                intent = new Intent(Intent.ACTION_USER_SWITCHED);
19069                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19070                        | Intent.FLAG_RECEIVER_FOREGROUND);
19071                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19072                broadcastIntentLocked(null, null, intent,
19073                        null, null, 0, null, null,
19074                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19075                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19076            }
19077        } finally {
19078            Binder.restoreCallingIdentity(ident);
19079        }
19080    }
19081
19082    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19083            final int newUserId) {
19084        final int N = mUserSwitchObservers.beginBroadcast();
19085        if (N > 0) {
19086            final IRemoteCallback callback = new IRemoteCallback.Stub() {
19087                int mCount = 0;
19088                @Override
19089                public void sendResult(Bundle data) throws RemoteException {
19090                    synchronized (ActivityManagerService.this) {
19091                        if (mCurUserSwitchCallback == this) {
19092                            mCount++;
19093                            if (mCount == N) {
19094                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19095                            }
19096                        }
19097                    }
19098                }
19099            };
19100            synchronized (this) {
19101                uss.switching = true;
19102                mCurUserSwitchCallback = callback;
19103            }
19104            for (int i=0; i<N; i++) {
19105                try {
19106                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19107                            newUserId, callback);
19108                } catch (RemoteException e) {
19109                }
19110            }
19111        } else {
19112            synchronized (this) {
19113                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19114            }
19115        }
19116        mUserSwitchObservers.finishBroadcast();
19117    }
19118
19119    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19120        synchronized (this) {
19121            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19122            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19123        }
19124    }
19125
19126    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19127        mCurUserSwitchCallback = null;
19128        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19129        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19130                oldUserId, newUserId, uss));
19131    }
19132
19133    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19134        synchronized (this) {
19135            if (foreground) {
19136                moveUserToForeground(uss, oldUserId, newUserId);
19137            }
19138        }
19139
19140        completeSwitchAndInitalize(uss, newUserId, true, false);
19141    }
19142
19143    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19144        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19145        if (homeInFront) {
19146            startHomeActivityLocked(newUserId, "moveUserToFroreground");
19147        } else {
19148            mStackSupervisor.resumeTopActivitiesLocked();
19149        }
19150        EventLogTags.writeAmSwitchUser(newUserId);
19151        getUserManagerLocked().userForeground(newUserId);
19152        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19153    }
19154
19155    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19156        completeSwitchAndInitalize(uss, newUserId, false, true);
19157    }
19158
19159    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19160            boolean clearInitializing, boolean clearSwitching) {
19161        boolean unfrozen = false;
19162        synchronized (this) {
19163            if (clearInitializing) {
19164                uss.initializing = false;
19165                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19166            }
19167            if (clearSwitching) {
19168                uss.switching = false;
19169            }
19170            if (!uss.switching && !uss.initializing) {
19171                mWindowManager.stopFreezingScreen();
19172                unfrozen = true;
19173            }
19174        }
19175        if (unfrozen) {
19176            final int N = mUserSwitchObservers.beginBroadcast();
19177            for (int i=0; i<N; i++) {
19178                try {
19179                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19180                } catch (RemoteException e) {
19181                }
19182            }
19183            mUserSwitchObservers.finishBroadcast();
19184        }
19185        stopGuestUserIfBackground();
19186    }
19187
19188    /**
19189     * Stops the guest user if it has gone to the background.
19190     */
19191    private void stopGuestUserIfBackground() {
19192        synchronized (this) {
19193            final int num = mUserLru.size();
19194            for (int i = 0; i < num; i++) {
19195                Integer oldUserId = mUserLru.get(i);
19196                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19197                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19198                        || oldUss.mState == UserStartedState.STATE_STOPPING
19199                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19200                    continue;
19201                }
19202                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19203                if (userInfo.isGuest()) {
19204                    // This is a user to be stopped.
19205                    stopUserLocked(oldUserId, null);
19206                    break;
19207                }
19208            }
19209        }
19210    }
19211
19212    void scheduleStartProfilesLocked() {
19213        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19214            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19215                    DateUtils.SECOND_IN_MILLIS);
19216        }
19217    }
19218
19219    void startProfilesLocked() {
19220        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19221        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19222                mCurrentUserId, false /* enabledOnly */);
19223        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19224        for (UserInfo user : profiles) {
19225            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19226                    && user.id != mCurrentUserId) {
19227                toStart.add(user);
19228            }
19229        }
19230        final int n = toStart.size();
19231        int i = 0;
19232        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19233            startUserInBackground(toStart.get(i).id);
19234        }
19235        if (i < n) {
19236            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19237        }
19238    }
19239
19240    void finishUserBoot(UserStartedState uss) {
19241        synchronized (this) {
19242            if (uss.mState == UserStartedState.STATE_BOOTING
19243                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19244                uss.mState = UserStartedState.STATE_RUNNING;
19245                final int userId = uss.mHandle.getIdentifier();
19246                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19247                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19248                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19249                broadcastIntentLocked(null, null, intent,
19250                        null, null, 0, null, null,
19251                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19252                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19253            }
19254        }
19255    }
19256
19257    void finishUserSwitch(UserStartedState uss) {
19258        synchronized (this) {
19259            finishUserBoot(uss);
19260
19261            startProfilesLocked();
19262
19263            int num = mUserLru.size();
19264            int i = 0;
19265            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19266                Integer oldUserId = mUserLru.get(i);
19267                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19268                if (oldUss == null) {
19269                    // Shouldn't happen, but be sane if it does.
19270                    mUserLru.remove(i);
19271                    num--;
19272                    continue;
19273                }
19274                if (oldUss.mState == UserStartedState.STATE_STOPPING
19275                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19276                    // This user is already stopping, doesn't count.
19277                    num--;
19278                    i++;
19279                    continue;
19280                }
19281                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19282                    // Owner and current can't be stopped, but count as running.
19283                    i++;
19284                    continue;
19285                }
19286                // This is a user to be stopped.
19287                stopUserLocked(oldUserId, null);
19288                num--;
19289                i++;
19290            }
19291        }
19292    }
19293
19294    @Override
19295    public int stopUser(final int userId, final IStopUserCallback callback) {
19296        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19297                != PackageManager.PERMISSION_GRANTED) {
19298            String msg = "Permission Denial: switchUser() from pid="
19299                    + Binder.getCallingPid()
19300                    + ", uid=" + Binder.getCallingUid()
19301                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19302            Slog.w(TAG, msg);
19303            throw new SecurityException(msg);
19304        }
19305        if (userId <= 0) {
19306            throw new IllegalArgumentException("Can't stop primary user " + userId);
19307        }
19308        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19309        synchronized (this) {
19310            return stopUserLocked(userId, callback);
19311        }
19312    }
19313
19314    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19315        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19316        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19317            return ActivityManager.USER_OP_IS_CURRENT;
19318        }
19319
19320        final UserStartedState uss = mStartedUsers.get(userId);
19321        if (uss == null) {
19322            // User is not started, nothing to do...  but we do need to
19323            // callback if requested.
19324            if (callback != null) {
19325                mHandler.post(new Runnable() {
19326                    @Override
19327                    public void run() {
19328                        try {
19329                            callback.userStopped(userId);
19330                        } catch (RemoteException e) {
19331                        }
19332                    }
19333                });
19334            }
19335            return ActivityManager.USER_OP_SUCCESS;
19336        }
19337
19338        if (callback != null) {
19339            uss.mStopCallbacks.add(callback);
19340        }
19341
19342        if (uss.mState != UserStartedState.STATE_STOPPING
19343                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19344            uss.mState = UserStartedState.STATE_STOPPING;
19345            updateStartedUserArrayLocked();
19346
19347            long ident = Binder.clearCallingIdentity();
19348            try {
19349                // We are going to broadcast ACTION_USER_STOPPING and then
19350                // once that is done send a final ACTION_SHUTDOWN and then
19351                // stop the user.
19352                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19353                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19354                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19355                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19356                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19357                // This is the result receiver for the final shutdown broadcast.
19358                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19359                    @Override
19360                    public void performReceive(Intent intent, int resultCode, String data,
19361                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19362                        finishUserStop(uss);
19363                    }
19364                };
19365                // This is the result receiver for the initial stopping broadcast.
19366                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19367                    @Override
19368                    public void performReceive(Intent intent, int resultCode, String data,
19369                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19370                        // On to the next.
19371                        synchronized (ActivityManagerService.this) {
19372                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19373                                // Whoops, we are being started back up.  Abort, abort!
19374                                return;
19375                            }
19376                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19377                        }
19378                        mBatteryStatsService.noteEvent(
19379                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19380                                Integer.toString(userId), userId);
19381                        mSystemServiceManager.stopUser(userId);
19382                        broadcastIntentLocked(null, null, shutdownIntent,
19383                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19384                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19385                    }
19386                };
19387                // Kick things off.
19388                broadcastIntentLocked(null, null, stoppingIntent,
19389                        null, stoppingReceiver, 0, null, null,
19390                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19391                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19392            } finally {
19393                Binder.restoreCallingIdentity(ident);
19394            }
19395        }
19396
19397        return ActivityManager.USER_OP_SUCCESS;
19398    }
19399
19400    void finishUserStop(UserStartedState uss) {
19401        final int userId = uss.mHandle.getIdentifier();
19402        boolean stopped;
19403        ArrayList<IStopUserCallback> callbacks;
19404        synchronized (this) {
19405            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19406            if (mStartedUsers.get(userId) != uss) {
19407                stopped = false;
19408            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19409                stopped = false;
19410            } else {
19411                stopped = true;
19412                // User can no longer run.
19413                mStartedUsers.remove(userId);
19414                mUserLru.remove(Integer.valueOf(userId));
19415                updateStartedUserArrayLocked();
19416
19417                // Clean up all state and processes associated with the user.
19418                // Kill all the processes for the user.
19419                forceStopUserLocked(userId, "finish user");
19420            }
19421
19422            // Explicitly remove the old information in mRecentTasks.
19423            removeRecentTasksForUserLocked(userId);
19424        }
19425
19426        for (int i=0; i<callbacks.size(); i++) {
19427            try {
19428                if (stopped) callbacks.get(i).userStopped(userId);
19429                else callbacks.get(i).userStopAborted(userId);
19430            } catch (RemoteException e) {
19431            }
19432        }
19433
19434        if (stopped) {
19435            mSystemServiceManager.cleanupUser(userId);
19436            synchronized (this) {
19437                mStackSupervisor.removeUserLocked(userId);
19438            }
19439        }
19440    }
19441
19442    @Override
19443    public UserInfo getCurrentUser() {
19444        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19445                != PackageManager.PERMISSION_GRANTED) && (
19446                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19447                != PackageManager.PERMISSION_GRANTED)) {
19448            String msg = "Permission Denial: getCurrentUser() from pid="
19449                    + Binder.getCallingPid()
19450                    + ", uid=" + Binder.getCallingUid()
19451                    + " requires " + INTERACT_ACROSS_USERS;
19452            Slog.w(TAG, msg);
19453            throw new SecurityException(msg);
19454        }
19455        synchronized (this) {
19456            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19457            return getUserManagerLocked().getUserInfo(userId);
19458        }
19459    }
19460
19461    int getCurrentUserIdLocked() {
19462        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19463    }
19464
19465    @Override
19466    public boolean isUserRunning(int userId, boolean orStopped) {
19467        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19468                != PackageManager.PERMISSION_GRANTED) {
19469            String msg = "Permission Denial: isUserRunning() from pid="
19470                    + Binder.getCallingPid()
19471                    + ", uid=" + Binder.getCallingUid()
19472                    + " requires " + INTERACT_ACROSS_USERS;
19473            Slog.w(TAG, msg);
19474            throw new SecurityException(msg);
19475        }
19476        synchronized (this) {
19477            return isUserRunningLocked(userId, orStopped);
19478        }
19479    }
19480
19481    boolean isUserRunningLocked(int userId, boolean orStopped) {
19482        UserStartedState state = mStartedUsers.get(userId);
19483        if (state == null) {
19484            return false;
19485        }
19486        if (orStopped) {
19487            return true;
19488        }
19489        return state.mState != UserStartedState.STATE_STOPPING
19490                && state.mState != UserStartedState.STATE_SHUTDOWN;
19491    }
19492
19493    @Override
19494    public int[] getRunningUserIds() {
19495        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19496                != PackageManager.PERMISSION_GRANTED) {
19497            String msg = "Permission Denial: isUserRunning() from pid="
19498                    + Binder.getCallingPid()
19499                    + ", uid=" + Binder.getCallingUid()
19500                    + " requires " + INTERACT_ACROSS_USERS;
19501            Slog.w(TAG, msg);
19502            throw new SecurityException(msg);
19503        }
19504        synchronized (this) {
19505            return mStartedUserArray;
19506        }
19507    }
19508
19509    private void updateStartedUserArrayLocked() {
19510        int num = 0;
19511        for (int i=0; i<mStartedUsers.size();  i++) {
19512            UserStartedState uss = mStartedUsers.valueAt(i);
19513            // This list does not include stopping users.
19514            if (uss.mState != UserStartedState.STATE_STOPPING
19515                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19516                num++;
19517            }
19518        }
19519        mStartedUserArray = new int[num];
19520        num = 0;
19521        for (int i=0; i<mStartedUsers.size();  i++) {
19522            UserStartedState uss = mStartedUsers.valueAt(i);
19523            if (uss.mState != UserStartedState.STATE_STOPPING
19524                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19525                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19526                num++;
19527            }
19528        }
19529    }
19530
19531    @Override
19532    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19533        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19534                != PackageManager.PERMISSION_GRANTED) {
19535            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19536                    + Binder.getCallingPid()
19537                    + ", uid=" + Binder.getCallingUid()
19538                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19539            Slog.w(TAG, msg);
19540            throw new SecurityException(msg);
19541        }
19542
19543        mUserSwitchObservers.register(observer);
19544    }
19545
19546    @Override
19547    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19548        mUserSwitchObservers.unregister(observer);
19549    }
19550
19551    private boolean userExists(int userId) {
19552        if (userId == 0) {
19553            return true;
19554        }
19555        UserManagerService ums = getUserManagerLocked();
19556        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19557    }
19558
19559    int[] getUsersLocked() {
19560        UserManagerService ums = getUserManagerLocked();
19561        return ums != null ? ums.getUserIds() : new int[] { 0 };
19562    }
19563
19564    UserManagerService getUserManagerLocked() {
19565        if (mUserManager == null) {
19566            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19567            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19568        }
19569        return mUserManager;
19570    }
19571
19572    private int applyUserId(int uid, int userId) {
19573        return UserHandle.getUid(userId, uid);
19574    }
19575
19576    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19577        if (info == null) return null;
19578        ApplicationInfo newInfo = new ApplicationInfo(info);
19579        newInfo.uid = applyUserId(info.uid, userId);
19580        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19581                + info.packageName;
19582        return newInfo;
19583    }
19584
19585    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19586        if (aInfo == null
19587                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19588            return aInfo;
19589        }
19590
19591        ActivityInfo info = new ActivityInfo(aInfo);
19592        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19593        return info;
19594    }
19595
19596    private final class LocalService extends ActivityManagerInternal {
19597        @Override
19598        public void onWakefulnessChanged(int wakefulness) {
19599            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19600        }
19601
19602        @Override
19603        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19604                String processName, String abiOverride, int uid, Runnable crashHandler) {
19605            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19606                    processName, abiOverride, uid, crashHandler);
19607        }
19608    }
19609
19610    /**
19611     * An implementation of IAppTask, that allows an app to manage its own tasks via
19612     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19613     * only the process that calls getAppTasks() can call the AppTask methods.
19614     */
19615    class AppTaskImpl extends IAppTask.Stub {
19616        private int mTaskId;
19617        private int mCallingUid;
19618
19619        public AppTaskImpl(int taskId, int callingUid) {
19620            mTaskId = taskId;
19621            mCallingUid = callingUid;
19622        }
19623
19624        private void checkCaller() {
19625            if (mCallingUid != Binder.getCallingUid()) {
19626                throw new SecurityException("Caller " + mCallingUid
19627                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19628            }
19629        }
19630
19631        @Override
19632        public void finishAndRemoveTask() {
19633            checkCaller();
19634
19635            synchronized (ActivityManagerService.this) {
19636                long origId = Binder.clearCallingIdentity();
19637                try {
19638                    if (!removeTaskByIdLocked(mTaskId, false)) {
19639                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19640                    }
19641                } finally {
19642                    Binder.restoreCallingIdentity(origId);
19643                }
19644            }
19645        }
19646
19647        @Override
19648        public ActivityManager.RecentTaskInfo getTaskInfo() {
19649            checkCaller();
19650
19651            synchronized (ActivityManagerService.this) {
19652                long origId = Binder.clearCallingIdentity();
19653                try {
19654                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19655                    if (tr == null) {
19656                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19657                    }
19658                    return createRecentTaskInfoFromTaskRecord(tr);
19659                } finally {
19660                    Binder.restoreCallingIdentity(origId);
19661                }
19662            }
19663        }
19664
19665        @Override
19666        public void moveToFront() {
19667            checkCaller();
19668            // Will bring task to front if it already has a root activity.
19669            startActivityFromRecentsInner(mTaskId, null);
19670        }
19671
19672        @Override
19673        public int startActivity(IBinder whoThread, String callingPackage,
19674                Intent intent, String resolvedType, Bundle options) {
19675            checkCaller();
19676
19677            int callingUser = UserHandle.getCallingUserId();
19678            TaskRecord tr;
19679            IApplicationThread appThread;
19680            synchronized (ActivityManagerService.this) {
19681                tr = recentTaskForIdLocked(mTaskId);
19682                if (tr == null) {
19683                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19684                }
19685                appThread = ApplicationThreadNative.asInterface(whoThread);
19686                if (appThread == null) {
19687                    throw new IllegalArgumentException("Bad app thread " + appThread);
19688                }
19689            }
19690            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19691                    resolvedType, null, null, null, null, 0, 0, null, null,
19692                    null, options, callingUser, null, tr);
19693        }
19694
19695        @Override
19696        public void setExcludeFromRecents(boolean exclude) {
19697            checkCaller();
19698
19699            synchronized (ActivityManagerService.this) {
19700                long origId = Binder.clearCallingIdentity();
19701                try {
19702                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19703                    if (tr == null) {
19704                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19705                    }
19706                    Intent intent = tr.getBaseIntent();
19707                    if (exclude) {
19708                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19709                    } else {
19710                        intent.setFlags(intent.getFlags()
19711                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19712                    }
19713                } finally {
19714                    Binder.restoreCallingIdentity(origId);
19715                }
19716            }
19717        }
19718    }
19719}
19720